ItemsControl和Canvas中的多个dataTemplates

时间:2018-04-17 14:06:06

标签: c# wpf xaml mvvm datatemplate

我试图在画布上显示一些框(我自己的userControl在其自己的xaml文件中定义,名为singleNodeControl)并用线连接(正常的xaml Line元素绑定到LineToParent类)

这两个项目都存储在viewModel的绑定列表中,该列表是<UserControl>类型。这两个类(框和行)扩展UserControl类,所以我可以将它们存储到单个绑定列表(canvasNodeSourceList)

.cs文件中的SingleNodeControl类包含代码以及.xaml文件中的模板。

LineToParent类仅包含.cs代码,其中我存储X1,X2,Y1,Y2 coordiantes以便以后绑定它们。

带有itemsControl的xaml看起来。我认为如果canvasNodeSourceList中的项目是LineToParent类型,它将使用模板bellow othervise它将使用存储在singleNodeControl xaml文件中的模板(更多贝娄)。

但看起来没有使用lineTemplate for line。绘制SingleNodeCOntrols,但行不是。我错过了哪些模板?甚至可以在外部文件中定义一些模板,在项目控件中定义一些模板吗?

我只是想显示一些盒子(需要xaml定义因为它们有多个内部元素),这些盒子可以通过线连接。

<ItemsControl x:Name="content" ItemsSource="{Binding canvasNodeSourceList}">                    
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate >
            <Canvas x:Name="contentCanvas" Background="White" Width="{Binding Width}" Height="{Binding Height}"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>                   
    <ItemsControl.Resources>
    <DataTemplate DataType="{x:Type slider:LineToParent}">
              <!--<Line X1="100" Y1="100" X2="10000" Y2="10000" StrokeThickness="5" Stroke="RED"></Line>-->
            <Line X1="{Binding leftPos1}" Y1="{Binding topPos1}" X2="{Binding leftPos2}" Y2="{Binding topPos2}" StrokeThickness="5" Stroke="Black"></Line>
        </DataTemplate>

    </ItemsControl.Resources>                  
</ItemsControl>

SingleNodeControl xaml文件

<UserControl x:Class="WHS_qa.View.SingleNodeControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WHS_qa.View"
         mc:Ignorable="d"              
         >
<Grid>
    <Border BorderBrush="Black" BorderThickness="2">
        <StackPanel Name="NodeStackPanel">


        </StackPanel>
    </Border>

</Grid>

我还尝试修改itemsControl看起来像这样(将itemsControl.Resource更改为itemsControl.itemTemplate)并显示了testline(包含所有singleNodeControl元素)但是输出充满了错误

<ItemsControl x:Name="content" ItemsSource="{Binding canvasNodeSourceList}">                    
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate >
            <Canvas x:Name="contentCanvas" Background="White" Width="{Binding Width}" Height="{Binding Height}"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>                   
    <ItemsControl.ItemTemplate>
    <DataTemplate DataType="{x:Type slider:LineToParent}">
              <Line X1="100" Y1="100" X2="10000" Y2="10000" StrokeThickness="5" Stroke="RED"></Line>
            <!--<Line X1="{Binding leftPos1}" Y1="{Binding topPos1}" X2="{Binding leftPos2}" Y2="{Binding topPos2}" StrokeThickness="5" Stroke="Black"></Line>-->
        </DataTemplate>

    </ItemsControl.ItemTemplate>                  
</ItemsControl>

输出错误

System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='LineToParent'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='SingleNodeControl'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='LineToParent'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='SingleNodeControl'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='LineToParent'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='SingleNodeControl'
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='LineToParent'

1 个答案:

答案 0 :(得分:0)

当您根据类型设置样式时,您不需要项目模板。这是因为您的模板将基于数据类型 但是,您需要将datatemplate用于将放在itemscontrol的itemssource中的所有数据类型。

此示例在itemscontrol thingm中绘制画布,模板化各种对象:

https://1drv.ms/u/s!AmPvL3r385QhgooJ94uO6PopIDs4lQ

 <ItemsControl x:Name="ic" ItemsSource="{Binding Items}"
                      Background="{StaticResource bgroundImage}">
            <ItemsControl.Resources>
                <DataTemplate DataType="{x:Type local:RectangleVM}">
                    <Rectangle Stroke="Green" Fill="White" 
                               Width="{Binding Width,Mode=TwoWay}"
                               Height="{Binding Height,Mode=TwoWay}"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:CircleVM}" >
                    <StackPanel>
                        <Ellipse Stroke="Red" Fill="White" 
                                 Width="{Binding EllipseWidth}" 
                                 Height="{Binding EllipseHeight}"
                                 />
                    </StackPanel>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:TextBoxVM}">
                    <TextBox Text="{Binding TbText}"/>
                </DataTemplate>
            </ItemsControl.Resources>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Name="TheCanvas"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Top" Value="{Binding Top}"/>
                    <Setter Property="Canvas.Left" Value="{Binding Left}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>

您可能还希望在项容器上绑定canvas.left和canvas.top。

所有类型的样本在该样本中都有很大不同。如果您有类似的项目,则可以为大多数或部分项目使用基类,即使您提供子类型也会被识别。