Wpf Treeview Binding



WPF Controls ItemsControl TreeView HierarchicalDataTemplate WPF TreeView HierarchicalDataTemplate binding to. WPF Frame Control WPF Controls ContentControl Frame WPF frame control is capable of displaying both WPF and HTML content. WPF TreeViewWPF TreeView Control IntroductionWPF TreeView HeadersWPF TreeView Data BindingWPF TreeView Multiple TemplatesWPF TreeView Selection/Expansion StateWPF TreeView Lazy LoadingAs WPF Tutorial says in their website post TreeView, data binding and multiple templates “The WPF TreeView supports data binding, as pretty much all other WPF controls do, but because the TreeView is. Treeview is one control in wpf that you have to appoach in a little diffrent manner.It is simple and efficient and at the same time a pain to understand and get in track for a beginer,especially those coming from the windows appliaction backgroud.Please go through the MVVM pattern first and then try to approach the treeview.

  1. Wpf Treeview Binding Dictionary
  2. Wpf Treeview Binding Selecteditem

The longer I work with WPF, the more I notice how many things it’s missing. Recently I realized that TreeView.SelectedItem property is read-only and non-bindable. I think there’s no point explaining why binding SelectedItem would be useful, so there should be no surprise in my disappointment.

I googled the problem and every resource I’ve found was guiding me into either handling it in code-behind or adding IsSelected property to my model class. Both of these approaches suffer from the same problem — an item won’t get selected if its parents are not yet expanded. This was a deal-breaker for me because I wanted the tree view to navigate to the newly selected item, even if it wasn’t immediately visible.

I solved this problem by writing a small behavior that takes care of this for me.

Wpf

Custom behavior

I realized that to solve this I would have to traverse the entire hierarchy of tree nodes, but that wasn’t the only problem. To access IsSelected and IsExpanded properties I needed to resolve a reference to an instance of TreeViewItem, which is a container that wraps around the data template.

This in itself can be accomplished by using the TreeViewItem.ItemContainerGenerator.ContainerFromItem(…) method. However, if the node is not visible yet then the container is also not initialized, making the method return null.

Treeview

In order to make our target node visible, we need to expand all of its ancestor nodes one by one, starting from the very top. I naively assumed that by expanding the node from code, its children’s item containers will immediately become available but this is not the case because that’s handled asynchronously. We can, however, subscribe to the Loaded event of each data item which will trigger once the control has been loaded.

Generally, the approach looks like this:

  • Subscribe to Loaded events of all data items using a style.
  • When SelectedItem changes, go through all loaded tree nodes and try to locate the target node.
  • If we manage to find it, select it and exit early.
  • If we instead find its parent, expand it so that we can continue the search once it’s loaded.
  • When one of the nodes we expanded is loaded, it triggers an event and we start again from the top.

Here’s the behavior I’ve implemented:

To make it easier to check if a node is a child of another node, I defined a property called HierarchyPredicate. If it’s not set, the behavior will just blindly expand all nodes until it finds the item we’re looking for. The predicate can help optimize this process.

Once this behavior is attached, it calls UpdateTreeViewItemStyle() to inject an event handler for Loaded event of ItemContainerStyle. We need to listen to this event to handle nodes that were expanded. To ensure maximum compatibility, it extends an existing style if it can find one or creates a new one otherwise.

It also calls UpdateAllTreeViewItems() after attaching. This goes through all of tree view’s children and in turn calls UpdateTreeViewItem(…) on them.

Usage

You can attach this behavior to a tree view like this:

When SelectedItem is changed from the view model, the behavior traverses the hierarchy while utilizing HierarchyPredicate to find the correct node, ultimately selecting it. An optional parameter ExpandSelected dictates whether the selected item should be expanded as well.

If the user changes SelectedItem from the UI, it works like you would expect and propagates the new value to the view model.

To bind the RadTreeView to a collection use its ItemsSource property and define HierarchicalDataTemplate that are needed to display the data from the collection. If you want the changes to the collection to be automatically reflected to the RadTreeView items, the collection should inherit from ObservableCollection, or to implement the INotifyPropertyChanged interface.

The following tutorial will guide you how to bind a RadTreeView to a collection of business objects.

Wpf Treeview Binding Dictionary

The final result should look like the snapshot below:

Wpf treeview binding hierarchicaldatatemplate
  • First, you need to include the following assemblies in your XAML declaration:

    • Telerik.Windows.Controls
    • Telerik.Windows.Controls.Navigation
  • Create a new class named Team. The class has a single string property.

  • Create a new class named Division. The class has a single string property - Name and a collection with teams.

  • Create a new class named League. The class has a single string property and a collection with divisions objects. Practically, a collection of League objects will be the data source for the treeview.

  • Create a new class named RadTreeViewSampleData. This will be the data source (the model) for the RadTreeView. The class has a reference to an ObservableCollection of League objects and a single method which initializes the data.

  • The next step is to declare the RadTreeViewSampleData as a resource in your application.

    The sampleData alias points to the assembly where your data source is located.

  • Since the data is hierarchical, you need to declare a HierarchicalDataTemplate. If you want to learn about the hierarchical data template, read the topic about Hierarchical Data Templates.

  • Finally, here is the treeview declaration. For ItemsSource is used the DataSource resource. For ItemTemplate is set the created in the previous step hierarchical data template.

  • If you run the demo, the final result should look like the snapshot below.

Wpf Treeview Binding Selecteditem

See Also