Примечание. Решение см. В нижней части этого поста.
Я пытаюсь использовать «HierarchicalDataTemplate» XAML для отображения XML-документа в TreeView.Мой текущий код XAML будет отображать первый дочерний узел «Parent», но не последующие дочерние узлы разных типов.
Могу ли я использовать XAML для отображения дочерних элементов разных типов под общим родителем?
Я свел проблему к очень простому образцу в иллюстративных целях.
Я хочу, чтобы мое древовидное представление выглядело так (за исключением содержимого в скобках):
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
В этом примере у «родительских» узлов есть 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>