WPF TreeView Nodes and Sub Nodes

2.5k views Asked by At

How would I modify my current TreeView to support a parent node of 'Critical, Alert' and then the child nodes would be the messages of that severity type. I'm using an ObservableCollection that is tied to the TreeView. There is more data in each message type but I only want a few of them to be visible to the user. Then when a user clicks on one of the child nodes, pull the other data from that item in the collection and display it where it's needed. I added the ID as hidden because i'm not sure if I need something to reference that is unique to reference that item in the collection. I also want to default a different icon for each parent node, the child nodes wont have an icon.

Hope I describe this so it's understandable.

XMAL

 <TreeView x:Name="tvMessages" HorizontalAlignment="Left" Height="262" Margin="10,37,0,0" VerticalAlignment="Top" Width="248">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding Icon}" />
                            <TextBlock Text="{Binding Description}" />
                            <TextBlock Text="{Binding ID}" Visibility="Hidden" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>

MessageData

public class MessageData
{
    public Guid ID { get; set; }
    public string Severity { get; set; }
    public string Description { get; set; }
    public string ClientID { get; set; }
    public string Specialty { get; set; }
    public DateTime IssuedDate { get; set; }
}
2

There are 2 answers

0
AudioBubble On BEST ANSWER

Its a bit old, but this MSDN blog should get you in the right direction http://blogs.msdn.com/b/mikehillberg/archive/2009/10/30/treeview-and-hierarchicaldatatemplate-step-by-step.aspx

0
Sheridan On

To display hierarchical data... you need to have hierarchical data. The easiest way to do that is to add a collection (for the child nodes) of type MessageData into your MessageData class:

public class MessageData
{
    public Guid ID { get; set; }
    public string Severity { get; set; }
    public string Description { get; set; }
    public string ClientID { get; set; }
    public string Specialty { get; set; }
    public DateTime IssuedDate { get; set; }
    public ObservableCollection<MessageData> Messages { get; set; }
}

The change required for the XAML is also small:

<TreeView x:Name="tvMessages" ItemsSource="{Binding YourMessageDataObservableCollection}" HorizontalAlignment="Left" Height="262" Margin="10,37,0,0" VerticalAlignment="Top" Width="248">
    <TreeView.Resources>
        <DataTemplate DataType="{x:Type YourxmlNamespacePrefix:MessageData}">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Icon}" />
                <TextBlock Text="{Binding Description}" />
                <TextBlock Text="{Binding ID}" Visibility="Hidden" />
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Messages}" />
    </TreeView.ItemTemplate>
</TreeView>

Points to note:

  • You should be Binding your ObservableCollection to the TreeView.ItemsSource property.
  • You should implement the INotifyPropertyChange interface in your MessageData class if you want your UI to update when the data is changed.
  • By adding the DataTemplate into the TreeView.Resources section without setting the x:Key property, it will explicitly be set on all MessageData instances in the TreeView.