Binding a TreeView to a DataSet
This blog entry demonstrates the fundamentals of binding a WPF TreeView to a DataSet with two related DataTables. The technique presented herein could easily be extended to fit more sophisticated requirements, such as binding to more than two tables.
Many applications need to display hierarchical data in a TreeView, and often that data is retrieved from a database. In many situations the developer just needs to bind the TreeView directly to the DataSet which was populated with database data; creating custom domain objects and collections of those objects can be overkill sometimes. If you are currently in that situation, rest assured that it is actually fairly trivial to do this in WPF.
The basic gist of the solution is to bind the top level of TreeViewItems against the master DataTable, and then bind against DataRelations for any descendants of the root nodes. You need to use a HierarchicalDataTemplate for every non-leaf level of nodes, in other words, only the very lowest DataTable in the hierarchy is displayed with a non-hierarchical DataTemplate.
Let’s just get right into an example. Here is a method in a class called DataSetCreator which creates a DataSet with two related DataTables:

The resultant DataSet has two DataTables (‘Master’ and ‘Detail’) and one DataRelation (‘Master2Detail’). We want a TreeView to display the Master rows as top-level nodes and the Detail rows as children of their respective parent node. Here is the XAML for a Window which contains a TreeView configured to load and display that data:

If you had, say, three related tables (Master –> Detail –> DetailInfo) then you could have the ‘DetailTemplate’ be a HierarchicalDataTemplate whose ItemsSource was bound to the DataRelation between ‘Detail’ and ‘DetailInfo,’ and the ItemTemplate a DataTemplate which displays the pertinent information in that table.
When you run the demo application and expand the root nodes, the TreeView looks like this:

Click here to download the demo project. Be sure to change the file extension from DOC to ZIP and then unzip it.

May 5, 2007 at 1:31 pm
It is really easier than with “classic” WinForms !
May 5, 2007 at 2:51 pm
Matthieu,
It certainly is. The WinForms TreeView does not provide any way to automatically generate its nodes based on a data source. The WPF TreeView makes this very easy. WPF rocks!
Josh
May 11, 2007 at 2:36 am
[...] Josh Smith on WPF - Hierarchal Data Binding [...]
May 16, 2007 at 8:39 pm
I am a complete noob at this so bear with me.
When I open the Window1.xaml, I get an error:
Assembly ” was not found. The ‘clr-namespace’ URI refers to an assembly that is not referenced by the project.
Am I missing something?
May 16, 2007 at 8:51 pm
I had a look through the WPF Forums and consensus was that this is a bug.
May 16, 2007 at 10:14 pm
Michael,
Visual Studio’s XAML support is not quite “there yet.” It gives warnings for perfectly valid XAML constructs, which you can safely ignore.
Josh
May 22, 2007 at 9:45 am
Is there any way to select a treeview node (arbitrary child object) by passing a key, like we used to do in Windows common control library. ?
When we want to select a Node, we could write this in VB6:
Set tvw.SelectedItem = tvw.Nodes.Items(”KEY1″
“KEY1″ is a unique key for every node, Unique key was assigned while populating the treeview.
Additionally how to use tvw.Items.Contains method ?
I think contains method only work at own level (not nested). Because Items collection is a new object for each child treeviewitem, this is very bad and consuming lots of memory, anyways, please help me.
Thanks.
Govind
May 22, 2007 at 9:52 am
Govind,
No, TreeViewItems in WPF do not have a Key property.
The Items collection of TreeView only contains the data objects represented by the root-level nodes. You must use a recursive technique to walk through the items and set the IsSelected property to true on the TreeViewItem which you want to select.
Josh
May 22, 2007 at 10:19 am
Thanks Josh, But IsSelected is a read-only property, I remebered
I tried the recursive technique for checking the desired object existance, But I think ICompare interface can help me for nodes comparsion this will also help me in sorting the tree, I will try this.
Additionally, I saw a method in Items property called MoveToCurrent (not exactly sure the name) as per doc it will select given node or will return false upon failure. But this method is also doesn’t work for me and always returns fails even I passed a true object. I will submit my code tomorrow. Many many thanks for replying.
Govind
May 22, 2007 at 10:44 am
Govind,
You should post further questions/code on the WPF Forum: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=119&SiteID=1
Josh
June 13, 2007 at 9:47 am
Hi,
What about the case where you have a single table with a self reference?
I’ve tried to modify the code but no luck
June 13, 2007 at 10:04 am
George,
Hmmm, that’s an interesting question. You might want to search the WPF Forum, or post a question about it if you can’t find an answer. I’ve never tried to do that in WPF before.
Josh
August 12, 2007 at 8:16 am
I used this binding(solution1), works good, but some thing works else then if I fill TreeView by treeview.Items.Add() (solution2).
For example:
1) change Foreground of selected node. I get from treeview.SelectedItem
Sol 2: TreeViewItem
Sol 1: DataRowView
> So how can I access to treeviewitem.Foreground, if I get DataRowItem, respectively, how to change color of text of selected node?
2) using treeview.FindName(registeredName)
>What is registered name in sol 1? So how can I find node if I know ID of row from table to be able for example change text color?
Any help welcome.
Thanks,
Marek
September 6, 2007 at 11:59 pm
Hi,
i have bound the TreeView to the Dataset and geet the Item. But they not TreeView Item . Neither I can TypeCast them to Treeview. Actually i want to write a Event Handleron the click of the Items. How can I do this?
Bye
September 7, 2007 at 6:37 am
For general purpose questions about WPF, you should ask them on the WPF Forum: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=119&SiteID=1 First search the forum to see if the question has already been answered.
If you have a question which relates to the topic of a blog post, then leave it as a comment on that post.
Thanks,
Josh
September 11, 2007 at 11:15 pm
Hi,
Can we do this when there are more than a DataRelation and I Want multiple levels i.e Nested Nodes.
Thanks
Abhinav
September 12, 2007 at 9:53 am
Hi.
Help me please. A need more as two tables bind to a treeview. Between tables in dataset I have relations. But this work onlly between two tables.
Can we write any examle me.
I have Visual C# 2008 Express.
Radek
September 12, 2007 at 10:03 am
Abihav,
This post mentions that situation, under the xaml snippet.
Radek,
I’m not going to write an example for you. If you have a question which needs to be answered with any urgency, don’t post it here. Post it to the WPF Forum: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=119&SiteID=1
Josh
September 22, 2007 at 12:18 pm
Very informative example. Thanks for the write up!
December 12, 2007 at 3:31 am
Hi,
The code works fine to fill a treeview with a dataset.
But, since you don’t use a treeview.item, how can you directly expand the whole treeview?
Freddy.
January 28, 2008 at 7:29 am
[...] http://joshsmithonwpf.wordpress.com/2007/05/05/binding-a-treeview-to-a-dataset/ [...]
January 30, 2008 at 4:42 am
Hi Freddy,
You should use a style for this (put it in the Xaml file, before the treeview :
greetz
Geert D.
January 30, 2008 at 4:46 am
Hi Freddy,
Put this in your XAML file (before the treeview). ( Change the ‘{’ to ”, had do this, because the code wouldn’t post otherwise)
{ResourceDictionary}
{Style TargetType=”TreeViewItem”}
{Setter Property=”IsExpanded” Value=”True”/}
{/Style}
{/ResourceDictionary}
greetz
Geert
May 1, 2008 at 4:37 am
Great TreeView, but is there any way to implement sorting of the tree nodes??
I have tried sorting the data withjin the dataset but I can’t get the tree view to update - any ideas??
May 1, 2008 at 6:54 am
Kieran,
When you bind to a collection, you’re actually binding to an ICollectionView implementation wrapped around the collection. ICollectionView supports sorting.
Josh
May 5, 2008 at 12:20 pm
What about one table which is arranged with parentID and ObjectID kind a like internal hirarchy ?
any ideas how not to break balls around this issue please ?
ADV thanks ANCE
May 11, 2008 at 11:01 am
Hi Josh!
You showed an example with Dataset. What about LINQ to SQL classes? I couldn’t find anything bout that. Can you help me, please? Thanx…
May 24, 2008 at 11:24 pm
[...] http://joshsmithonwpf.wordpress.com/2007/05/05/binding-a-treeview-to-a-dataset/ [...]
May 25, 2008 at 3:01 am
[...] http://joshsmithonwpf.wordpress.com/2007/05/05/binding-a-treeview-to-a-dataset/ [...]
June 15, 2008 at 9:43 am
[...] http://joshsmithonwpf.wordpress.com/2007/05/05/binding-a-treeview-to-a-dataset/ [...]