XML数据绑定到TreeView,同一父节点下具有不同类型的子节点

时间:2010-10-29 13:47:46

标签: wpf xml data-binding treeview

注意:请参阅此帖子的底部了解解决方案。

我正在尝试使用XAML的“HierarchicalDataTemplate”在TreeView中显示xml文档。 我当前的XAML代码将显示“父”节点的第一个子节点,但不显示不同类型的后续子节点。

我可以使用XAML在普通家长下显示不同类型的孩子吗?

为了说明的目的,我把这个问题归结为一个非常基本的样本。

我希望我的treeview看起来像这样(减去括号中的内容):

Parent: Roger (Type="Parent")
 |--Rug rats (Type="Children")
 |     |--Bob (Type="Child")
 |     |--Tom
 |
 |--Gear (Type="Equipment")  <-- **can't display this or its child nodes**
       |--Canoe (Type="Item")
       |--Tent

在此示例中,“Parent”节点有2种类型的子节点; “儿童”和“装备”。

这是XML:

<Parent Name="Roger">
   <Children>
     <Child Name="Bob"/>
     <Child Name="Tom"/>
  </Children>
  <EquipmentList>
     <Item Name="Canoe"/>
     <Item Name="Tent"/>
   </EquipmentList>
</Parent>

这是用于呈现树节点的XAML数据模板:

<Window.Resources>
    <HierarchicalDataTemplate DataType="Parent" ItemsSource="{Binding XPath=Children}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text=": "/>
            <TextBlock Text="{Binding XPath=@Name, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="Children" ItemsSource="{Binding XPath=Child}">
        <TextBox Width="Auto" Text="Rug Rats" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="Child">
        <TextBox Width="Auto" Text="{Binding XPath=@Name, UpdateSourceTrigger=PropertyChanged}" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="EquipmentList" ItemsSource="{Binding XPath=Item}">
        <TextBox Width="Auto" Text="Gear" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="Item">
        <TextBox Width="Auto" Text="{Binding XPath=@Name, UpdateSourceTrigger=PropertyChanged}" />
    </HierarchicalDataTemplate>

</Window.Resources>

为了完整性,以下是填充树的代码:

_xmlDoc = new XmlDocument();
_xmlDoc.Load(@"..\..\SampleXMLFile.xml");

treeViewToolDescription.ItemsSource = _xmlDoc;

我一直在谷歌搜索“XML”,“TreeView”,“HierarchicalDataTemplate”和“异构”的组合几天,所以我看到(但显然没有理解)很多文章看起来很有希望,但似乎永远不够相关。

解决方案是使用ItemsSource的星号来获取所有子项,无论类型如何,ItemsSource =“{Binding XPath = *}”

之前(ItemsSource显式设置为“Children”):

    <HierarchicalDataTemplate DataType="Parent" ItemsSource="{Binding XPath=Children}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Parent: "/>
            <TextBlock Text="{Binding XPath=@Name, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </HierarchicalDataTemplate>

之后(ItemsSource设置为“*”而不是指定类型):

    <HierarchicalDataTemplate DataType="Parent" ItemsSource="{Binding XPath=*}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Parent: "/>
            <TextBlock Text="{Binding XPath=@Name, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </HierarchicalDataTemplate>

1 个答案:

答案 0 :(得分:2)

简短的回答是你现在不能。您需要创建一个属性,将给定节点的所有子节点整理为一个属性。

因此,在这种情况下,您需要一个SubNodes属性,如下所示

Parent.SubNodes => a list {Rug Rats, Gear}
Children.SubNodes for Rug Rats=> a list {Bob, Tom} 
Equipment.SubNodes for Gear => a list {Canoe, Tent} Items

并且您可以为每种类型使用DataTemplates来呈现每个叶节点的外观。一个类似的问题WPF TreeView HierarchicalDataTemplate - binding to object with multiple child collections