In my previous article on the same topic I described how to replace the ItemsPresenter of RadComboBox with a RadTreeView. It was as simple as updating the control template. Unfortunately the controls’ selection synchronization relied on a bug in RadComboBox that we recently fixed – the control was able to have a value in its SelectedItem property, that was not present in its Items collection. Now, in order to workaround this new problem, we have to either inherit RadComboBox, or create an attached behavior that will allow us to get the SelectedItem of the inner RadTreeView. The code you have to write is virtually the same in Silverlight and WPF:

<UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/TreeViewInComboBox;component/RadComboBoxStyle.xaml" /> </ResourceDictionary.MergedDictionaries> <telerik:HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Children}"> <TextBlock Text="{Binding Text}" /> </telerik:HierarchicalDataTemplate> </ResourceDictionary> </UserControl.Resources> <StackPanel x:Name="LayoutRoot"> <local:TreeViewCombo x:Name="treeViewCombo" ItemsSource="{Binding}" ItemTemplate="{StaticResource ItemTemplate}" Style="{StaticResource TreeViewInComboBox}" /> <TextBlock Text="{Binding ElementName=treeViewCombo, Path=SelectedTreeViewItem.Text}" /> </StackPanel>


The important parts from the new RadComboBoxStyle.xaml are the ContentPresenter and RadTreeView declarations in the RadComboBox EditableTemplate:

<ContentPresenter x:Name="ContentPresenterElement" IsHitTestVisible="False" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" Content="{Binding SelectedValue, ElementName=treeView}" />

<telerikNavigation:RadTreeView x:Name="treeView" ItemTemplate="{TemplateBinding ItemTemplate}" ItemsSource="{TemplateBinding ItemsSource}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />

For more information, check the attached solution that contains 4 projects – two for Silverlight and two for WPF, demonstrating both attached behavior and inherited combo box:

As a bonus I am also attaching one more application, demonstrating how to mix the “old” approach for the same problem, with the self-referencing treeview example from yesterday – in this case, the Items collection of RadComboBox contains all treeview items and there is no problem to bind the RadTreeView SelectedValue property with RadComboBox SelectedItem. In this case we only need to update the RadTreeView declaration in RadComboBoxStyle.xaml – no inheritance, no attached properties, just small XAML change and everything works:

<ScrollViewer x:Name="PART_ScrollViewer" BorderThickness="0" VerticalScrollBarVisibility="Auto" telerik:StyleManager.Theme="{StaticResource Theme}"> <ScrollViewer.Resources> <local:HierarchyConverter x:Key="HierarchyConverter" /> </ScrollViewer.Resources> <!--It is important not to touch the SelectedValuePath property on this RadTreeView --> <telerikNavigation:RadTreeView x:Name="treeView" ItemTemplate="{TemplateBinding ItemTemplate}" ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource HierarchyConverter}}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedValue="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" /> </ScrollViewer>



I hope this helps.

Related Posts