Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在画布上绘制路径列表?_C#_Wpf_Xaml_Mvvm_Wpf Controls - Fatal编程技术网

C# 如何在画布上绘制路径列表?

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只绘制

在我的WPFMVVM应用程序中,我有一个
ListBox
,其中
Canvas
作为它的
ItemsPanel
。当用户单击按钮时,列表框的项目将由用户动态创建—
ListBox。ItemsSource
是存储在my
MainViewModel
中的
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>