#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 для привязки к пользовательскому классу. Поэтому, если значения из пользовательского интерфейса изменены, пользовательский интерфейс обновляется