Silverlight and WPF ComboBox with TreeView inside

The TreeView is useful control, but it has one shortcoming: it occupies too much space in the application. That’s why I’ve decided to create the custom control which looks like a ComboBox but displays the TreeView instead of the list.

Here is the final result:

Although this control looks quite simple, the actual implementation isn’t clear and takes long time.
Here is the sequence of steps:

1) Custom TreeView and TreeViewItem. They provide the following functionality:

  • Allow to expand and  select an item from a view model (It isn’t possible to select an item of the TreeView using other ways)
  • The event which is fired when a user clicks a TreeViewItem (so it will be possible to close the ComboBox)

2) Interface for an item of the ItemsSource collection

public interface ITreeViewItemModel
	string SelectedValuePath { get; }
	string DisplayValuePath { get; }

	bool IsExpanded { get; set; }
	bool IsSelected { get; set; }

	IEnumerable<ITreeViewItemModel> GetHierarchy();
	IEnumerable<ITreeViewItemModel> GetChildren();

Members of this interface:

  • IsExpanded – allows to expand the TreeViewItem from the bound view model. Must be implemented as the INotifyPropertyChanged property.
  • IsSelected – allows to select the TreeViewItem from the bound view model. Must be implemented as the INotifyPropertyChanged property.
  • SelectedValuePath – the unique string (unique item id) that will be used to select and expand the treeview control
  • DisplayValuePath – the content that will be displayed at the header when the combobox is closed
  • GetHierarchy – returns the item and its parents
  • GetChildren – returns child items of the current item

3. Create the Combobox

It is the most difficult part of the implementation. I was forced to create many methods to provide the connection between Combobox and TreeView. But although there is many private methods, there is only two public properties:

  • SelectedItem – now it is possible to get or set this item and it will be selected in the treeview.
  • SelectedHierarchy – it wasn’t necessary to create this property, but it wasn’t difficult so I’ve decided to implement it. Use list of strings instead of the actual item.

4. Add it to a view and bind with a view model:

    <Windows:HierarchicalDataTemplate x:Key="treeViewDataTemplate" 
                   ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Title}" />
<Grid x:Name="LayoutRoot" Background="White">
        <local:ComboBoxTreeView ItemsSource="{Binding Items}" 
             SelectedItem="{Binding SelectedItem}" 
             ItemTemplate="{StaticResource treeViewDataTemplate}"
             HorizontalAlignment="Center" VerticalAlignment="Top" />

The ItemTemplate property is obligatory property and must be of the HierarchicalDataTemplate type.

Silverlight version:
WPF version:
The updated source code which supports the ‘SelectionChanged’ event of the combobox: