Canvas не обновляется, пока не будет перемещено окно WPF

#c# #.net #wpf #graphics

#c# #.net #wpf #графика

Вопрос:

У меня есть простое окно WPF с холстом в нем, и на холсте есть объект Path с GeometryGroup внутри пути:

 <Path
      Stroke="Red"
      StrokeThickness="3">
    <Path.Data>
        <GeometryGroup Children="{Binding Elements}" />
    </Path.Data>
</Path>
  

Поэтому я инициализирую коллекцию элементов перед InitializeComponent() вызовом, и она отображается правильно. После этого с помощью System.Timers.Timer я обновляю точки существующей фигуры, чтобы они перемещались. Это работает. Но проблема в том, что я вижу, что Canvas обновляет свой результат только при перемещении окна WPF мышью. Если я оставлю его там, то последнее изображение просто зависнет там, но точки будут обновлены.

Я вижу это, когда снова начинаю перемещать окно WPF, и фигуры перемещаются в свое последнее местоположение.

Есть какие-нибудь идеи о том, как это исправить и почему он это делает?

Комментарии:

1. Я предполагаю, что вы делегировали ur для обработки потока пользовательского интерфейса, если нет, это выдаст ошибку. Поправьте меня, если я ошибаюсь, но с использованием System. Windows. Многопоточность. DispatcherTimer может быть лучше, поскольку он вызывается непосредственно в потоке пользовательского интерфейса

2. Да, я делаю, как вы сказали, так что это работает, но мне нужно выполнить вычисления в другом потоке и обновить пользовательский интерфейс. Я только обновляю элементы, но для этого все еще требуется, чтобы это было сделано в потоке пользовательского интерфейса.

3. хорошо, хотите попробовать это? Для canvas, я полагаю, это что-то вроде canvas.left. Выполните простое 1. После того, как вы выполните свои вычисления, попробуйте изменить значение canvas. слева от вашего потока вычислений. Если вы можете вызвать объект, попробуйте выполнить invoke . Пример показан здесь : cskardon.wordpress.com/2008/01/03/invoking-ui-changes-in-wpf

Ответ №1:

Вам необходимо реализовать INotifyPropertyChanged в классе, к которому вы привязываетесь, а список элементов должен реализовывать INotifyCollectionChanged , например ObservableCollection . Как только вы это сделаете, таймеры или диспетчеры не понадобятся.

Комментарии:

1. Спасибо, но из-за этого я не использую таймер. Это похоже на игровое приложение, где вычисления должны выполняться в отдельном потоке с регулярными интервалами для оценки игрового мира. Также я не могу использовать ObservableCollection, потому что GeometryGroup. Дочерним элементам требуется GeometryCollection.

2. @Joan, я довольно давно не касался WPF, но, если я могу вспомнить, ObservableCollection очень полезен. Я вспомнил, что использовал ObservableCollection для привязки к пользовательскому классу. Поэтому, если значения из пользовательского интерфейса изменены, пользовательский интерфейс обновляется