Мне нужно реализовать масштабирование и панорамирование вокруг оси X в моей программе просмотра графика движения автобусов (и, возможно, редакторе), написанной на C # / WPF. Я мог бы использовать простые преобразования, но учтите, что когда расстояние между точками увеличивается, размер точек остается неизменным. Кроме того, названия автобусных станций должны оставаться в фиксированных положениях слева, независимо от того, как я панорамирую график:

При текущем подходе все визуальные элементы отображаются на одном элементе ItemsControl с Canvas в качестве ItemsPanel и несколькими шаблонами данных, по одному для каждого типа фигуры (точка, сегмент, линия разделения времени, линия станции). Итак, каждая фигура привязана к соответствующему ViewModel, который имеет свойства PosX и PosY, предоставленные Canvas:
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left"
Value="{Binding Path=PosX, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="Canvas.Top"
Value="{Binding Path=PosY, UpdateSourceTrigger=PropertyChanged}" />
</Style>
</ItemsControl.ItemContainerStyle>
Когда мне нужно выполнить панорамирование или масштабирование, я вызываю OnPropertyChanged («PosX») для модели представления каждой фигуры. Затем свойство пересчитывается с новыми значениями свойств PanX и ZoomX всего графа:
public double PosX
{
get
{
return _scheduleGraphViewModel.ZoomX * _shedulePointModel.PlanTime + _scheduleGraphViewModel.PanX;
}
}
Проблема в том, что это работает намного медленнее, чем я надеялся. На 1000+ баллов это практически непригодно. Профилировщик говорит мне, что узкое место находится внутри метода OnPropertyChanged.
Я предполагаю, что весь подход неверен, но я не могу найти или придумать лучшее решение.