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.