Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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# ItemsControl仅显示每个对象的第一项_C#_.net_Wpf_Data Binding - Fatal编程技术网

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>