C# 如何在画布上绘制路径列表?
在我的WPFMVVM应用程序中,我有一个C# 如何在画布上绘制路径列表?,c#,wpf,xaml,mvvm,wpf-controls,C#,Wpf,Xaml,Mvvm,Wpf Controls,在我的WPFMVVM应用程序中,我有一个ListBox,其中Canvas作为它的ItemsPanel。当用户单击按钮时,列表框的项目将由用户动态创建—ListBox。ItemsSource是存储在myMainViewModel中的DataContext元素列表(自定义类型) 目前,我的元素类使用X和Y坐标(以便可以在我的列表框的画布上绘制)和一些名为ShapeGeometry的数据来描述简单对象,这些数据将作为路径绘制。这是它的数据模板: 如您所见,这允许我为每个ListBoxItem只绘制
ListBox
,其中Canvas
作为它的ItemsPanel
。当用户单击按钮时,列表框的项目将由用户动态创建—ListBox。ItemsSource
是存储在myMainViewModel
中的DataContext
元素列表(自定义类型)
目前,我的元素
类使用X和Y坐标(以便可以在我的列表框的画布上绘制)和一些名为ShapeGeometry
的数据来描述简单对象,这些数据将作为路径绘制。这是它的数据模板
:
如您所见,这允许我为每个ListBoxItem只绘制一个特定路径。相反,我希望我的ListBoxItem是一个包含
元素
项列表的ComplexElement
,这意味着现在绘制的项将由不同数量的路径组成。现在,我关于如何实现这一点的想法是将ListBoxItem
定义为ListBox
,将ViewBox
+Canvas
定义为它的ItemsPanel
,就像它在上层一样,但它似乎过于复杂,可能会被证明有点低效(如果不是几百个项目,我打算有几十个)。有没有更简单的方法?我是否可以避免在每个ListBoxItem
中都有列表框?如果您想减少开销并拥有一个列表,您应该能够使用DataGrid控件交换ListBox
然后将画布添加到。或者,您可以在RowDetailsTemplate中放置第二个列表框。我建议您使用自定义控件(该控件具有列表框或任何您想要的内容)作为ListBox.ItemTemplate的DataTemplate,通过这种方式,您可以降低ListBox的复杂性,并且cutomized控件可以通过实现您自己的逻辑来满足您的需要 1.定义控件类 2.定义模板
//你想要什么
3.使用它
顺便提一下
1.我建议您不要使用canvas作为ListBox的ItemsPanel,它可能会禁用虚拟化,这可能会在ItemsSource巨大时降低性能
2.似乎您需要一个嵌套的列表框,因此如果ItemTemplate发生变化,您可以使用“ItemTemplateSelector”,选中此项。但请记住,选择器可能是“静态”的,这意味着在初始化时只能选择一次datatemplate
3.此外,如果您希望项目在某些情况下更改其自身的行为,请尝试在模板中使用触发器或在定义类中执行该操作。ShapeGeometry(路径的
数据与之绑定)可以是GeometryGroup
。谢谢,我会尝试一下。但是ItemsPanel必须是画布,因为小元素可能需要在特定点上旋转和缩放(双击后可以在单独的窗口中编辑“复杂项”),除非您有更好的想法。
public class MyListItem : Control
{
//Define the property/event/control logic you want
static MyListItem ()
{
//Remeber this to override the default style
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyListItem ), new FrameworkPropertyMetadata(typeof(MyListItem )));
}
}
<Style TargetType="{x:Type my:MyListItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type my:MyListItem}">
<Border>
<ListBox ItemsSource={Binding YourDetailList}>
<ListBox.ItemTemplate>
//Anything you want here
</ListBox.ItemTemplate>
</ListBox>
</Boder>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<my:MyListItem/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>