How can I use HierarchicalDataTemplate to display XML Elements and Attributes? How can I use HierarchicalDataTemplate to display XML Elements and Attributes? wpf wpf

How can I use HierarchicalDataTemplate to display XML Elements and Attributes?


I added an ItemsControl into the template, like this :

<Window.Resources>  <SolidColorBrush x:Key="xmlValueBrush" Color="Blue" />  <SolidColorBrush x:Key="xmAttributeBrush" Color="Red" />  <SolidColorBrush x:Key="xmlTagBrush" Color="DarkMagenta" />  <SolidColorBrush x:Key="xmlMarkBrush" Color="Blue" />  <DataTemplate x:Key="attributeTemplate">    <StackPanel Orientation="Horizontal"                Margin="3,0,0,0"                HorizontalAlignment="Center">      <TextBlock Text="{Binding Path=Name}"                 Foreground="{StaticResource xmAttributeBrush}"/>      <TextBlock Text="=""                 Foreground="{StaticResource xmlMarkBrush}"/>      <TextBlock Text="{Binding Path=Value}"                 Foreground="{StaticResource xmlValueBrush}"/>      <TextBlock Text="""                 Foreground="{StaticResource xmlMarkBrush}"/>    </StackPanel>  </DataTemplate>  <HierarchicalDataTemplate x:Key="nodeTemplate">    <StackPanel Orientation="Horizontal"        Focusable="False">      <TextBlock x:Name="tbName" Text="?" />      <ItemsControl          ItemTemplate="{StaticResource attributeTemplate}"          ItemsSource="{Binding Path=Attributes}"          HorizontalAlignment="Center">        <ItemsControl.ItemsPanel>          <ItemsPanelTemplate>            <StackPanel Orientation="Horizontal"/>          </ItemsPanelTemplate>        </ItemsControl.ItemsPanel>      </ItemsControl>    </StackPanel>    <HierarchicalDataTemplate.ItemsSource>      <Binding XPath="child::node()" />    </HierarchicalDataTemplate.ItemsSource>    <HierarchicalDataTemplate.Triggers>      <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">        <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Value}"/>      </DataTrigger>      <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">        <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}"/>      </DataTrigger>    </HierarchicalDataTemplate.Triggers>  </HierarchicalDataTemplate>  <XmlDataProvider x:Key="xmlDataProvider">  </XmlDataProvider></Window.Resources>

Now it displays element names and the set of attributes and their values, like this:

enter image description here


you also can use a template selector for the different node types and use the XPath node()|@* to loop thru all types of nodes:

<TreeView    x:Name="TreeView"    ItemsSource="{Binding}"    ItemTemplateSelector="{DynamicResource ResourceKey=NodeTemplateSelector}">    <TreeView.Resources>        <HierarchicalDataTemplate x:Key="TextTemplate">            <Grid>                <uixml:TextInputControl DataContext="{Binding}" />            </Grid>        </HierarchicalDataTemplate>        <HierarchicalDataTemplate x:Key="AttributeTemplate">            <Grid>                <uixml:AttributeInputControl DataContext="{Binding}" />            </Grid>        </HierarchicalDataTemplate>        <HierarchicalDataTemplate x:Key="NodeTemplate" >            <TextBlock Text="{Binding Path=Name}" />            <HierarchicalDataTemplate.ItemsSource>                <Binding XPath="child::node()|@*" />            </HierarchicalDataTemplate.ItemsSource>        </HierarchicalDataTemplate>        <ui:XmlTemplateSelector            x:Key="NodeTemplateSelector"            NodeTemplate="{StaticResource NodeTemplate}"            TextTemplate="{StaticResource TextTemplate}"            AttributeTemplate="{StaticResource AttributeTemplate}" />    </TreeView.Resources></TreeView>

and :

public class XmlTemplateSelector:DataTemplateSelector{    public DataTemplate NodeTemplate { get; set; }    public DataTemplate TextTemplate { get; set; }    public DataTemplate AttributeTemplate { get; set; }    public override DataTemplate SelectTemplate(object item, DependencyObject container) {        XmlNode node = (XmlNode)item;        switch (node.NodeType) {            case XmlNodeType.Attribute:                return AttributeTemplate;            case XmlNodeType.Element:                return NodeTemplate;            case XmlNodeType.Text:                return TextTemplate;        }        throw new NotImplementedException(String.Format("not implemented for type {0}", node.NodeType));    }}