【发布时间】:2018-09-27 13:12:03
【问题描述】:
我试图在画布上显示一些框(我自己的 userControl 在它自己的名为 singleNodeControl 的 xaml 文件中定义)并将它们与线连接(普通 xaml Line 元素绑定到 LineToParent 类)
这两项都存储在视图模型中的绑定列表中,该列表为<UserControl> 类型。这两个类(框和线)都扩展了 UserControl 类,因此我可以将它们存储到单个绑定列表(canvasNodeSourceList)中
SingleNodeControl 类包含 .cs 文件中的代码以及 .xaml 文件中的模板。
LineToParent 类仅包含 .cs 代码,我在其中存储 X1、X2、Y1、Y2 坐标以便以后绑定它们。
带有 itemsControl 的 xaml 看起来。我认为如果 canvasNodeSourceList 中的项目是 LineToParent 类型,它将使用下面的模板,否则它将使用存储在 singleNodeControl xaml 文件中的模板(更多如下)。
但似乎没有使用 line 的 dataTemplate。 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)并显示测试行(包含所有 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'
【问题讨论】:
-
视图模型中的项目集合不应包含 UI 元素。相反,集合应该包含数据项,DataTemplates 中的元素绑定到这些数据项(如this example)。
-
@Clemens 感谢您的提示,我知道这一点,但我无法想象如何将这种方法与我的 SingleNodeControl 一起使用。它类似于多个元素的容器(img、标签、texbox 等)。我如何为这些子元素填充数据而不在代码中创建它?
-
您的项目集合可能是
IEnumerable<object>,即包含任何内容。然后为不同的项目类型声明不同的 DataTemplates。 -
克莱门斯是对的。去看看链接上的例子。每种类型的元素都应该是它自己的类型,具有该元素所需的任何属性。将它们放在绑定到 UI 的 ObservableCollection
-
您的台词可能在那里,但都在画布中的
0,0。 ItemsControl 将每个项目包装在<ContentPresenter>中,您需要在ItemsContainerStyle中绑定位置,以便将定位应用于ContentPresenter,而不是应用于该标记内的元素。我在很久以前写过a blog post,并附上了一些视觉示例,这样您就可以看到实际渲染的内容。也许这有助于解释它?
标签: c# wpf xaml mvvm datatemplate