C# WPF,TreeView,绑定到集合中对象内部的属性

C# WPF,TreeView,绑定到集合中对象内部的属性,c#,wpf,xaml,mvvm,treeview,C#,Wpf,Xaml,Mvvm,Treeview,这可能没那么难,但我越来越困惑了 我想在视图中显示树状视图,但无法正确绑定数据 TemplateFamilyList集合是根对象。它将包含TemplateFamily对象的列表。每个TemplateFamily对象都将包含一个Template对象和一个名为TemplateParameterMembers的TemplateParameter对象列表。实际的Template类和实际的TemplateParameter类在其他属性中都有一个Name属性 因此,在我的ViewModel类中,我有一个填充

这可能没那么难,但我越来越困惑了

我想在视图中显示树状视图,但无法正确绑定数据

TemplateFamilyList集合是根对象。它将包含TemplateFamily对象的列表。每个TemplateFamily对象都将包含一个Template对象和一个名为TemplateParameterMembers的TemplateParameter对象列表。实际的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)));              
        }
    }
OP post中定义的本地命名空间为:

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类添加名称空间,例如:

public TemplateFamily(Template aTemplate, ObservableCollection<TemplateParameter> templatesParameters)
    {
        Template = aTemplate;
        Name = aTemplate.Name;
        TemplateParameterMembers = templatesParameters;
    }
xmlns:domain="clr-namespace:S.ModelDomain" 
并尝试在数据类型属性中使用它


我还怀疑我的XAML有问题,也许我应该有另一个分层数据模板?

在这种情况下,最好和最通用的(我认为)解决方案是为树中显示的每种类型的项定义一个模板,并将它们放在树的资源字典中。每个模板都应该使用
DataType
属性与相应的项目类型相关联。这样,将自动选择合适的模板,根据其类型显示每个项目。假设您的
TemplateParameter
类是在命名空间
S.ModelDomain
中名为
S.ModelDomain
的项目中定义的,并且
local
前缀是在XAML中正确定义的,这应该会给您预期的结果(我冒昧地剥离了XAML中不相关的属性):


不过,在XAML的根元素(通常是
窗口
用户控件
)上定义名称空间映射是常见的做法。请参阅此处的详细信息:

请注意,模板没有指定
x:Key
参数,尽管已放入资源字典中。在自动模板选择过程中需要考虑模板。这种模板称为隐式模板。这里有一个有用的链接:

xmlns:local="clr-namespace:TaskManager.Domain;assembly=TaskManager.Domain"
xmlns:local="clr-namespace:S.VisualStudioExtension"           
         local:ViewModelLocator.AutoWireViewModel="True"
xmlns:domain="clr-namespace:S.ModelDomain" 
<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>