WPF 中的可编辑图形

Editable graphics in WPF

我正在开发一个向 window 显示复杂图形的 WPF 应用程序。我需要这些图形是高度动态的,这意味着例如线条可以随时出现、消失或只是移动(通过鼠标交互或以编程方式)。

有没有办法不用每次都重建完整的显示列表就可以实现?一个典型的例子是数据点可以移动但其余部分不能移动的函数图。这些点可能是即时计算的,而不是存储在数组中,因此参考它们的图形表示很棘手。


代码示例(根据要求):

// Add a Line Element
myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 50;
myLine.HorizontalAlignment = HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
myGrid.Children.Add(myLine);

更新:

假设我绘制了三个函数。我画了轴、图例、刻度线……和三条曲线。

如果我想删除第二条曲线,现在有比重绘一切更好的方法吗?

我发现 DrawingGroup class 部分满足了我的需求,因为它允许对图形实体进行分组并将它们作为一个整体来处理。不管怎样,还是得跟踪每一组,才能分别编辑。

万一使用 DrawingVisual 而不是 CanvasGeometryGroup 也很方便。

Is there a way to achieve that without rebuilding the complete display list every time ?

这正是一般的 MVVM 模式和 WPF 模板一起旨在提供的。具体来说,除了这个之外,你没有描述你想要实现的大部分目标:

lines can appear, disappear or just be moved at any time

对我来说,这听起来像是两个模型 类,一个用于点(XY 坐标),一个用于线(包含对两个点的引用)。点模型是可观察的(即它实现 INotifyPropertyChanged 正确和完整),而线模型应该永远不会改变。

对于您的视图模型,您拥有的是 collection 个实体(类似 IEntity),这两个模型都是从中派生的。所以只是一个 ObservableCollection<IEntity> 类型的只读 属性。当您想从一条线上移动一个点时,只需更新其 X and/or Y 坐标即可。要添加一行吗?将点和连接它们的线添加到您的 collection。删除也一样。简单!

最后一部分,您的看法。这包含一个绑定到您的视图模型 collection 的 ItemsControl,面板模板设置为 <Canvas/>(以便能够直接设置位置)和 <DataTemplate> 资源,每个资源一个您拥有的模型类型:

  • 线条很简单,只需将它们的四个位置属性绑定到线模型中两个点模型的 XY 坐标即可绘制到位。
  • 点是你喜欢的地方,它们的目的是提供操纵器来移动它们,即响应拖动事件并更新其绑定属性的用户控件。因为线条包含对您的点的引用,所以直接更新点将在视觉上重新定位受影响的点以及连接它的线。