Based on @Sinatr's answer I was able to made a simplified version of the `DataTemplateSelector` which does not require the visual tree walk, so it should give the better, and most important, the fixed (`O(1)`) performance.
It's the same idea as per [@H.B. answer](https://stackoverflow.com/a/8279344/1997232): check whenever there is a `ComboBoxItem` as a parent in visual tree.
<!-- language: c# -->
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedTemplate { get; set; }
public DataTemplate DropDownTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return (container as FrameworkElement)?.TemplatedParent is ComboBoxItem
? DropDownTemplate
: SelectedTemplate;
}
}
Usage:
<ComboBox.ItemTemplateSelector>
<local:ComboBoxItemTemplateSelector>
<local:ComboBoxItemTemplateSelector.SelectedTemplate>
<DataTemplate>
... simple template for selected item
</DataTemplate>
</local:ComboBoxItemTemplateSelector.SelectedTemplate>
<local:ComboBoxItemTemplateSelector.DropDownTemplate>
<DataTemplate>
... complex template used by dropdown items
</DataTemplate>
</local:ComboBoxItemTemplateSelector.DropDownTemplate>
</local:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>
Use Item Template Selector. Define two properties SelectedTemplate and DropDownTemplate in Selector class. Check whether the container is wrapped in a ComboboxItem. If yes choose DropDownTemplate. If not choose SelectedTemplate.
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedTemplate { get; set; }
public DataTemplate DropDownTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var comboBoxItem = container.GetVisualParent<ComboBoxItem>();
if (comboBoxItem == null)
{
return SelectedTemplate;
}
return DropDownTemplate;
}
}
public static class DependencyObjectExtensions
{
public static T GetVisualParent<T>(this DependencyObject child) where T : FrameworkElement
{
while ((child != null) && !(child is T))
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
}
ComboBox in XAML,
<Page.Resources>
<local:ComboBoxItemTemplateSelector x:Key="selector">
<local:ComboBoxItemTemplateSelector.DropDownTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}"/>
<TextBlock Text="{Binding Name}" Margin="5 0 0 0"/>
</StackPanel>
</DataTemplate>
</local:ComboBoxItemTemplateSelector.DropDownTemplate>
<local:ComboBoxItemTemplateSelector.SelectedTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</local:ComboBoxItemTemplateSelector.SelectedTemplate>
</local:ComboBoxItemTemplateSelector>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ComboBox x:Name="combo"
ItemTemplateSelector="{StaticResource selector}">
</ComboBox>
</Grid>