Click here to Skip to main content
Click here to Skip to main content

Displaying XML in a WPF TreeView

, 23 Jan 2012
Rate this:
Please Sign up or sign in to vote.
In this article, I describe how to display data from a simple XML file in a WPF TreeView control.

Introduction

In this article, I will describe how to display data contained in a simple XML file using a TreeView control in a WPF application without writing any code. In this article, all of the magic is found in the XAML file that defines the window contents. Admittedly, you would not try to write a business application like this, but there may be something to learn here that will make that business application go together a little more easily.

Background

This article draws on information gleaned from two other articles about using XML with WPF that you may wish to read. The first is called Reaction to: A Simple WPF Explorer Tree by Josh Smith. In that article, Smith demonstrates how to use a DataTemplate to define the contents of TreeViewItems, and how the tree structure can be built using the window's "Loaded" event handler. The second article by Karl Shifflett took off from Smith's article. Shifflett's article is called Over Reaction To: A Simple WPF Explorer Tree. Shifflett's article described the HierarchicalDataTemplate demonstrating how it could be used to help recurse tree structure data to populate a TreeView control.

I found these two articles trying to find a solution to populate a TreeView with directory and file names similar to Window Explorer's directory tree, but including at least some filenames as well. While working that out, I had issues with strange behavior in the TreeView and decided to run some tests with XML data. That proved to be a bit of a challenge itself, but with information gleaned from Shifflett and Smith's articles, and a little use of the grey matter, I came up with the solution described below to populate a TreeView control with XML data.

Using the Code

It is actually fairly easy to display XML data using WPF. Other than the XML file itself, almost all of the work to enable this is done within XAML, and most of that is done by defining several resources. The source code available with this article is a complete working sample. The project is configured to use .NET 4.0, but you can move MainWindow.xaml and testdata.xml into a WPF 3.0 project, and it should work just as well.

In the text below, I will highlight just a sample of the XAML code that makes this work.

When you create a WPF project, a skeleton window is created in a file called MainWindow.xaml which opens in the Visual Studio editor. A little XAML is included to configure the default window with a Grid control to hold the rest of the visual elements of the window. In our code, we add a new child to the Window element right before the opening Grid tag, and below the opening Window tag, to create a section within Window to define some resources. To start out, the resources section looks like this:

<!-- This goes immediately after the opening Window tag -->
<Window.Resources>
</Window.Resources>

Then between those Window.Resources tags, we add several elements that will be used by the UI to display the XML data. The first resource we add is an XmlDataProvider. XmlDataProvider is a class that makes it possible to bind XML data to elements and work with the XML structure. An object is created by creating a resource from it like this:

<XmlDataProvider x:Key="xmldata"
                 Source="testdata.xml"
                 XPath="/root" />

The Source attribute is set to the name of the XML file we created for the test, but it does not actually reference a file during run time. By putting the file in the root directory of the project, and setting its build action to "Resource", the contents of the file are actually made a part of the assembly during compile time. So in this case, the filename becomes the key name for the resource, and WPF is smart enough to work out the details when the application runs. The XPath attribute is used to specify a node. The XML test file has a root node called "root", so we use that here to start the XML parsing with that node.

The really interesting work is done in data templates created with HierarchicalDataTemplate. Again, within the Window.Resources element, right below the XmlDataProvider, we create a data template for each type of tag used within the XML test file. In this case, three node items exist within testdata.xml, "root", "Node", and "leaf". So we create three data templates. The template for "Node" looks like this:

<HierarchicalDataTemplate DataType="Node"
                           ItemsSource="{Binding XPath=./*}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Margin="0"
                   Text="Node:" />
        <TextBlock Margin="5,0,0,0"
                   Text="{Binding XPath=@name}" />
    </StackPanel>
</HierarchicalDataTemplate>

The other templates are similar. The main difference to note is that the ItemsSource attribute was not specified for "leaf" nodes, because I knew that I placed no items within "leaf" nodes. Such nodes are always at the end of the line, so there is no reason to check them for contents. The ItemsSource attribute is provided by HierarchicalDataTemplate specifically for this use. HierarchicalDataTemplate uses ItemsSource to determine if the current item contains other items. If not, the node will be rendered accordingly, and navigation further down into the node is impossible. But if other items are contained within the current item, it will be rendered so that the user can drill down into the node to see the other items.

The last thing to do is to bind the XML data to the UI controls. I do that by setting the DataContext of the Grid, and the ItemsSource attribute of the TreeView control. The complete UI is defined within just a few lines.

<Grid DataContext="{StaticResource xmldata}">
    <TreeView Name="dirTree"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch"
          ItemsSource="{Binding}"
          VirtualizingStackPanel.IsVirtualizing="False"
          VirtualizingStackPanel.VirtualizationMode="Standard" />
</Grid>

That's it!

Points of Interest

The HierarchicalDataTemplate class made it very easy to populate the TreeView with XML data. There is no reason it could not be used in other scenarios to help in more complicated situations. The main things to remember are to create a template for each type expected by the TreeView (or else a parent type to catch several descending types) and to set the ItemsSource on types that may contain more data that needs to go into the TreeView.

History

  • January 20, 2012 - Original article.
  • January 21, 2012 - Cosmetic changes to correct code alignment.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Gil Yoder
Yoder's List
United States United States
Gil Yoder is an application performance analyst at Chevron. He has been working in their IT organization for about fifteen years. Before Chevron computer technology was more hobby than profession for him. He still considers it a hobby and enjoys learning about all of its aspects.
 
He starting learning how to program on a TRS-80 Model I computer with 4K RAM and 4K ROM. Those who can remember those days know that the 4K ROM contained all of the "OS" for the computer, and somewhat crippled version of Microsoft BASIC.
 
After a while he was able to upgrade the computer so that eventually he had a fully loaded 64K system, 48K RAM, and 16K ROM. With that he learned to program in BASIC and Z80 Assembly Language. He sold his first machine language program to 80-Micro Magazine (shortly before it folded) for $500. The program was a Z80 Debugger that sported a feature allowing single stepping within ROM.
 
At this time most of Yoder's free time is spent programming and learning about C#, WPF, SilverLight, MVVM, and other related technologies.
 
Mr. Yoder lives in a small suburb of Houston, TX with his wife. He and his wife have one daughter who is married and has two wonderful boys. Yoder looks forward to the day he can teach his grandsons how to design and create WPF controls.
Follow on   Twitter

Comments and Discussions

 
Questionuseful Pinmemberchaitanyasingh22-Oct-12 10:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 23 Jan 2012
Article Copyright 2012 by Gil Yoder
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid