带有线条和点的画布
本文关键字: | 更新日期: 2023-09-27 18:37:09
我正在迁移一个旧应用程序并尝试实现MVVM。 旧应用程序的界面与本文中描述的界面类似。 虽然它稍微简单一些。 我不太担心完全遵循 MVVM,但我想以此为契机练习。
我有以下课程:
public class LineViewModel
{
public ObservableCollection<LinePoint> Points {get;}
public Geometry LineGeometry {get;}
}
在我的应用程序视图模型中,我有一组线条,我想在画布上绘制这些线条,但我也想绘制构成每条线条的点。
这是我到目前为止的 XAML:
<ItemsControl ItemsSource="{Binding Lines}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:LineViewModel}">
<Path StrokeThickness="2.0" Stroke="Black" Data="{Binding LineGeometry}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:LinePoint}">
<Ellipse StrokeThickness="1.0" Stroke="Black" Fill="MistyRose" Width="8.0" Height="8.0" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我可以看到正在绘制的线,这似乎工作正常。 如您所见,我已经为点添加了模板,但我不知道如何设置 XAML 来绘制这些点。 我怎样才能画出点?
从线中提取点并从应用程序视图模型中公开这些点似乎违反直觉,因为是 LineViewModel 负责处理直线中的点,而不是应用程序。 如果我能提供帮助,我宁愿不将这些点与线条分开。
谢谢
我建议创建一个具有直线点的单个属性的视图模型
class LineViewModel
{
public PointCollection LinePoints { get; set; }
}
class ViewModel
{
public IEnumerable<LineViewModel> Lines { get; set; }
}
然后,您可以在"外部"ItemsControl的DataTemplate中嵌套ItemsControl,如下所示,它使用Polyline
来绘制线条,并使用Path
元素的集合,EllipseGeometries
用于圆圈。
<ItemsControl ItemsSource="{Binding Lines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Polyline Points="{Binding LinePoints}"
StrokeThickness="2.0" Stroke="Black"/>
<ItemsControl ItemsSource="{Binding LinePoints}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path StrokeThickness="1.0" Stroke="Black" Fill="MistyRose">
<Path.Data>
<EllipseGeometry Center="{Binding}"
RadiusX="4" RadiusY="4"/>
</Path.Data>
</Path>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
如果您必须按原样使用 LineViewModel,则可以编写如下所示的 ItemTemplate,并使用绑定转换器将您的LinePoint
转换为Point
,以便Center
椭圆几何。
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Path StrokeThickness="2.0" Stroke="Black" Data="{Binding LineGeometry}" />
<ItemsControl ItemsSource="{Binding Points}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path StrokeThickness="1.0" Stroke="Black" Fill="MistyRose">
<Path.Data>
<EllipseGeometry
Center="{Binding
Converter={StaticResource LinePointConverter}}"
RadiusX="4" RadiusY="4"/>
</Path.Data>
</Path>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>