[英]WPF, TreeView, Bind to properties inside object in Collection
这可能并不难,但是我越来越困惑。
我想在我的视图中显示一个TreeView,但是我无法正确获得数据绑定。
TemplateFamilyList集合是根对象。 它将包含TemplateFamily对象的列表。 每个TemplateFamily对象将包含一个Template对象和一个TemplateParameter对象列表,称为TemplateParameterMembers。 实际的Template类和实际的TemplateParameter类都具有Name属性以及其他属性。
因此,在我的ViewModel类中,我有一个填充集合的方法:
public void LoadTemplateTree()
{
TemplateFamilyList = new ObservableCollection<TemplateFamily>();
List<Template> templateList = BuilderService.GetAllTemplates();
List<TemplateParameter> templatesParametersList;
foreach (Template template in templateList)
{
templatesParametersList = BuilderService.GetATemplatesParameters(template.TemplateID);
TemplateFamilyList.Add(new TemplateFamily(template, new ObservableCollection<TemplateParameter>(templatesParametersList)));
}
}
这是TemplateFamily类:
public class TemplateFamily
{
public Template Template { get; set; }
public ObservableCollection<TemplateParameter> TemplateParameterMembers { get; set; }
public TemplateFamily(Template aTemplate, ObservableCollection<TemplateParameter> templatesParameters)
{
Template = aTemplate;
TemplateParameterMembers = templatesParameters;
}
}
我想要的是一个TreeView,例如:
NameOfTemplateB
等等
在我的XAML中,我有以下内容:(但无法正常工作,它只给出了箭头但没有名称,却给出了一些空白的树状视图)。
<TabItem Header="Template Files" Height="22" VerticalAlignment="Top">
<TreeView Height="Auto" Name="treeView1" Width="Auto" ItemsSource="{Binding TemplateFamilyList}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TemplateParameterMembers}" >
<TextBlock Text="{Binding Path=Name}" Margin="2" ></TextBlock>
</HierarchicalDataTemplate >
</TreeView.ItemTemplate>
</TreeView>
</TabItem>
ViewModel通过ViewModelLocator绑定到视图,在其他情况下也可以正常工作。 我知道如果绑定到TemplateFamilyList,它将得到正确的对象,我只是不知道如何在该列表中显示每个TemplateFamily的名称(应该是TemplateFamily对象的Template属性的Name属性),并且然后对于树中的下一个级别(如果存在TemplateParameterMembers列表),如何显示TemplateParameterMembers集合中每个项目的TemplateParameter属性的Name属性。
我想我可以尝试在TemplateFamily类中具有另一个属性Name,并在构造函数中简单地复制Template的Name属性,例如:
public TemplateFamily(Template aTemplate, ObservableCollection<TemplateParameter> templatesParameters)
{
Template = aTemplate;
Name = aTemplate.Name;
TemplateParameterMembers = templatesParameters;
}
但是我不喜欢这种方法,此外,我没有用于收集TemplateParameters的特殊“容器”类,因此,我仍然需要以某种方式向下钻取并获取TemplateParameters中每个项目的Name属性TemplateParameterMembers集合。
我看到了这篇文章 ,似乎在答案中,Gishu使用了DataType属性,例如:
DataType="{x:Type local:Group}
OP帖子中定义的本地名称空间为:
xmlns:local="clr-namespace:TaskManager.Domain;assembly=TaskManager.Domain"
但是,就我而言,Template和TemplateParameter类是我模型的一部分,它们甚至与ViewModel和View不在同一个项目中。 就我的本地名称空间而言,我有这个:
xmlns:local="clr-namespace:S.VisualStudioExtension"
local:ViewModelLocator.AutoWireViewModel="True"
然后,我应该为Template和TemplateParameter类添加一个名称空间,例如:
xmlns:domain="clr-namespace:S.ModelDomain"
并尝试在DataType属性中使用它?
我还怀疑我的XAML出了点问题,也许我应该拥有另一个Hierarchical DataTemplate?
在这种情况下,最好,最通用的解决方案是为将在树中显示的每种类型的项目定义一个模板,并将其放入树的资源字典中。 每个模板都应使用DataType
属性与相应的项目类型相关联。 这样,将自动选择合适的模板以根据其类型显示每个项目。 假设您的TemplateParameter
类是在名称空间S.ModelDomain
名为S.ModelDomain
的项目中定义的,并且local
前缀已在您的XAML中正确定义,那么这应该会给您带来预期的结果( 我剥夺了删除不相关属性的XAML的自由 ):
<TreeView xmlns:models="clr-namespace:S.ModelDomain;assembly=S.ModelDomain"
ItemsSource="{Binding TemplateFamilyList}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TemplateFamily}"
ItemsSource="{Binding TemplateParameterMembers}" >
<TextBlock Text="{Binding Template.Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type models:TemplateParameter}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
尽管在XAML的根元素(通常是Window
或UserControl
)上定义名称空间映射是很常见的做法。 在此处查看更多信息: WPF XAML的XAML命名空间和命名空间映射 。
请注意,尽管模板被放置在资源字典中,但并未指定x:Key
参数。 在自动模板选择过程中需要考虑模板。 这种模板称为隐式模板 。 这是一个有用的链接: 数据模板概述 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.