Search code examples
c#wpfxamlcomboboxdatatemplate

Displaying Image in ComboBox's selected item


I have a custom template for my WPF windows ComboBoxes, which display items that inherit from ComboBoxItem that also have an Image property (so that my items can display both text and an image). Both the text and image display as expected in the ComboBox's popup menu for any given item, but I haven't been able to display an image in the currently selected item.

The ContentPresenter within the ComboBox template that displays the currently selected item has its Content property properly bound to {TemplateBinding SelectionBoxItem}, and its ContentTemplate is bound to the following static resource:

    <DataTemplate x:Key="SelectionBoxItemTemplateTextAndImage" DataType="{x:Type SB:SBComboBoxItem}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Image}"/>
            <TextBlock Grid.Column="1" Text="{Binding}"/>
        </Grid>
    </DataTemplate>

SBComboBoxItem is the custom control that inherits from ComboBox and contains an "Image" property properly registered as a DependencyProperty.

I have attempted alternative implementations of that DataTemplate, including using:

{Binding Path=Image, RelativeSource={RelativeSource TemplatedParent}}

as the image's source. That didn't work, even though the text still displays when i set the TextBlock's Text property to:

{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}

I've played around and found numerous implementations that display the text, but the equivalents never work for the image. I don't understand why this doesn't work, as setting up the popup to display both images and text was a breeze.

Edit: Here's the added functionality to ComboBoxItem to handle the image, in case there's something I did wrong there:

    public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(Image), typeof(SBComboBoxItem));
    public Image Image { get { return (Image)GetValue(ImageProperty); } set { SetValue(ImageProperty, value); } }

And here is where I have a ComboBox with the items added:

<ComboBox SelectedIndex="1">
    <SB:SBComboBoxItem Content="Text">
        <SB:SBComboBoxItem.Image>
            <Image Source="..\Images\Table.png"/>
        </SB:SBComboBoxItem.Image>
    </SB:SBComboBoxItem>
    <SB:SBComboBoxItem Content="MoreText">
        <SB:SBComboBoxItem.Image>
            <Image Source="..\Images\Euclidian.png"/>
        </SB:SBComboBoxItem.Image>
    </SB:SBComboBoxItem>
</ComboBox>

Solution

  • Despite the fact that I was using a DataTemplate to expose the underlying type of my selected combobox item through DataTemplate's DataType property, the SelectionBoxItem property of my ComboBox was apparently returning something that could not be cast as my custom ComboBoxItem. I don't know why this is, nor why it did not fire any runtime errors, but I found that by binding to ComboBox's SelectedItem property instead of SelectionBoxItem in the ContentPresenter allowed me to access user defined properties.