Silverlight ComboBox with TreeView inside
April 29, 2011 15 Comments
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 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:
<UserControl.Resources>
<Windows:HierarchicalDataTemplate x:Key="treeViewDataTemplate"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Title}" />
</Windows:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<local:ComboBoxTreeView ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
ItemTemplate="{StaticResource treeViewDataTemplate}"
HorizontalAlignment="Center" VerticalAlignment="Top" />
</Grid>
The ItemTemplate property is obligatory property and must be of the HierarchicalDataTemplate type.
Here is the complete source code of this example: http://dl.dropbox.com/u/8047386/WordPress/ComboBoxTreeView.zip
The updated source code which supports the ‘SelectionChanged’ event of the combobox: ComboBoxTreeViewEventsSupport.zip
Show case: ComboBoxTreeViewTestPage.html









