C# ItemsControl仅显示每个对象的第一项
我在将线集合绘制到画布中时遇到问题。谷歌向我展示了几个来源,但我找不到一个真正的解决方案。我希望你们能给我一个提示 我的结构如下:C# ItemsControl仅显示每个对象的第一项,c#,.net,wpf,data-binding,C#,.net,Wpf,Data Binding,我在将线集合绘制到画布中时遇到问题。谷歌向我展示了几个来源,但我找不到一个真正的解决方案。我希望你们能给我一个提示 我的结构如下: public class CanvasLine { public Double X1 { get; set; } public Double X2 { get; set; } public Double Y1 { get; set; } public Double Y2 { get; set; } public Brush S
public class CanvasLine
{
public Double X1 { get; set; }
public Double X2 { get; set; }
public Double Y1 { get; set; }
public Double Y2 { get; set; }
public Brush StrokeColor { get; set; }
public Double StrokeThickness { get; set; }
public DoubleCollection StrokeDashArray { get; set; }
}
public class CanvasObject
{
public String Name { get; set; }
public ObservableCollection<CanvasLine> CanvasLines { get; set; }
}
public class ViewModel
{
...
public ObservableCollection<CanvasObject> CanvasObjects;
...
}
XAML:
这是为了演示,我可能删除了太多
我的问题是画布中只显示每个CanvasObject的第一条画布线。如果我放弃CanvaObject和DataContext={Binding CanvasLines}并直接将ItemsControl绑定到ObservableCollection,那么它可以正常工作,但是在接下来的步骤中,我需要添加更多的对象,并且我试图避免大量的行以保持某种对象结构
因为我是MVVM绑定的新手,所以我很高兴您能分享我的想法
问候。您不能在DataTemplate中绑定行的DataContext。它已保存对相应集合元素的引用 您实际需要的是嵌套的ItemsControl,外部用于CanvasObjects集合,内部用于CanvasLines:
<ItemsControl ItemsSource="{Binding CanvasObjects}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding CanvasLines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line Stroke="{Binding StrokeColor}"
StrokeDashArray="{Binding StrokeDashArray}"
StrokeThickness="{Binding StrokeThickness}">
...
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
现在,让您的XAML使用带有线条几何体的路径,而不是线条。然后将Transform属性分配给外部ItemsControl资源中的相应ScaleTransform:
<ItemsControl ItemsSource="{Binding CanvasObjects}">
<ItemsControl.Resources>
<ScaleTransform x:Key="lineTransform"
ScaleX="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType=ItemsControl}}"
ScaleY="{Binding ActualHeight,
RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding CanvasLines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path Stroke="{Binding Stroke}"
StrokeDashArray="{Binding StrokeDashArray}"
StrokeThickness="{Binding StrokeThickness}">
<Path.Data>
<LineGeometry
Transform="{StaticResource lineTransform}"
StartPoint="{Binding P1}"
EndPoint="{Binding P2}"/>
</Path.Data>
</Path>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
伟大的谢谢,我想这会把我推向正确的方向。我刚试过,似乎所有的线都显示出来了。他们中的大多数人都处于错误的位置和错误的风格,但这是另一个需要更多工作的问题。。。我认为嵌套项控件中的输入是错误的,对吗?至少我需要删除它才能看到线条。错误位置的问题是你删除了内部画布。ItemsControl在默认情况下使用StackPanel,这显然无法按您想要的方式工作。但是,内部画布从未获得大小集,因此多重绑定中的实际宽度绑定始终返回零。在我看来,转换线几何的方法不那么复杂。再次感谢,这似乎是合理的!您是对的,当再次放入内部画布时,实际宽度为0。接下来我将实现线几何的解决方案。仅供参考:有没有办法使用相对资源并指向第二个祖先?在这种情况下,外部项控制画布?有一个可设置为2的AncestorLevel。
public class CanvasLine
{
public Point P1 { get; set; }
public Point P2 { get; set; }
public Brush Stroke { get; set; }
public double StrokeThickness { get; set; }
public DoubleCollection StrokeDashArray { get; set; }
}
<ItemsControl ItemsSource="{Binding CanvasObjects}">
<ItemsControl.Resources>
<ScaleTransform x:Key="lineTransform"
ScaleX="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType=ItemsControl}}"
ScaleY="{Binding ActualHeight,
RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding CanvasLines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path Stroke="{Binding Stroke}"
StrokeDashArray="{Binding StrokeDashArray}"
StrokeThickness="{Binding StrokeThickness}">
<Path.Data>
<LineGeometry
Transform="{StaticResource lineTransform}"
StartPoint="{Binding P1}"
EndPoint="{Binding P2}"/>
</Path.Data>
</Path>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>