How to use a different template for selected and drop down states in combo box in Silverlight?
.net, combobox, silverlight, wpf, xaml
Solution
The ComboBox.ItemTemplate is just a convenient way to set the ComboBoxItem.ContentTemplate. So your code above basically tries to set the ComboBoxItem.ContentTemplate twice.
As Jobi pointed out, you could try to use just a custom Style. You can safely exclude the ContentPresenter, if you always know the type of the Content. The ContentPresenter just allows you to use a DataTemplate to display some random data. But you could just replace it with a TextBlock and an Image. You just lose the ability to specify a DataTemplate.
The problem with Jobi's approach is that the select item won't show it's image, even if it's in the drop-down. Really the selected item is displayed in two locations (the drop-down and the main body of the ComboBox). In one location you want one DataTemplate, and in you want a different DataTemplate in the other.
Your best bet is to restyle the ComboBox. You can get the default Style from here. There is a ContentPresenter with the name "ContentPresenter". You would need to:
- Remove/change the name of the ContentPresenter, so the ComboBox will not automatically set the Content/ContentTemplate properties
- Bind the ContentPresenter.Content property like so: "{TemplateBinding SelectedObject}"
- Set the ContentPresenter.ContentTemplate property to your DataTemplate without the Image
- Set the ComboBox.ItemTemplate property to the DataTemplate with an Image and TextBlock like you were
- Give the ComboBox Style an explicit key, like x:Key="MyComboBoxStyle"
- Use the Style on your ComboBox, like Style="{StaticResource MyComboBoxStyle}"
This effectively ignores the ComboBoxItem.ContentTemplate when displaying the selected item in the body of the ComboBox, but uses it when display the ComboBoxItem in the drop-down.
Problem
I can't seem to set a ContentTemplate for a ComboBoxItem. There reason I'm trying to do this is I want to have 2 appearances for my data in the combo box. When the combo box is open (menu is down) I want a text box (with the name of the image) and an image control below it. When I select the item I want the combo box to just show a text box with the name of the image. I thought I could achieve this by modifying the ItemTemplate and ItemContainerStyle of the ComboBox. The ItemContainerStyle contains the following ContentPresenter: ``` <ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> ``` So I assumed that I could just set the ContentTemplate here and it would work. But I can't seem to get it to work: ``` <DataTemplate x:Key="ComboBoxDataTemplate"> <Grid> <TextBlock Text="{Binding Path='Name'}"/> </Grid> </DataTemplate> <DataTemplate x:Key="ComboBoxItemTemplate"> <StackPanel> <TextBlock Text="{Binding Path='Name'}"/> <Image Source="{Binding Path='Source'}" Width="64" Height="64"/> </StackPanel> </DataTemplate> <Style x:Key="ComboBoxItemStyle1" TargetType="ComboBoxItem"> ... <Setter Property="ContentTemplate" Value="{StaticResource ComboBoxItemTemplate}"/> ... ``` Here's my combo box: ``` <ComboBox Width="70" Margin="3,0,0,0" ItemsSource="{StaticResource Source}" ItemTemplate="{StaticResource ComboBoxDataTemplate}" ItemContainerStyle="{StaticResource ComboBoxItemStyle1}" /> ``` The only way I can get this to work is to remove the ContentPresenter from the ItemContainerStyle, and replace it with the contents of my custom template (ComboBoxItemTemplate). But I didn't think I should use this approach as it would mean the ContentPresenter no longer exists (and code in the ComboBox might rely on it existing). Any help on showing a combo box with a different drop down and selected template would be greatly appreciated!