I have a combobox into which I load elements of this class
public class ComboBoxTypeItem
{
public string Type { get; set; }
public BitmapSource Icon { get; set; }
public ComboBoxTypeItem(string type)
{
this.Type = type;
switch (type)
{
case PLMC.SPEC_REQ_TYPE:
Icon = new BitmapImage(new Uri("Resources/spec.png", UriKind.Relative));
break;
case PLMC.RAZDEL_REQ_TYPE:
Icon = new BitmapImage(new Uri("Resources/rst.png", UriKind.Relative));
break;
case PLMC.REQ_TYPE:
Icon = new BitmapImage(new Uri("Resources/requirement.png", UriKind.Relative));
break;
case PLMC.REQ_ND_TYPE:
Icon = new BitmapImage(new Uri("Resources/requirementnd.png", UriKind.Relative));
break;
default:
break;
}
}
}
I need that when opening a combobox, the items to be selected are displayed as a list of strings with the values of the Name field, and when an item is selected in the combobox, the icon of the selected item (Icon field) is displayed.
For example - we have 3 items in cb (like item 1, item 2 and item 3) and if user click on cb, he will see popup with list of strings ("item 1", "item 2" and "item 3"). then he clicks on "item 2" and in header of cb he will see just icon of this item
I tried setting the binding via DisplayMemberPath, but it didn't help
To achieve this behavior—showing a list of strings when the ComboBox dropdown is open, and displaying only an icon when an item is selected—you can leverage WPF's data templating features. Specifically, you need to define separate DataTemplates for the dropdown items and the selected item view, and customize the ComboBox's control template.
ItemTemplate for the Dropdown: The ComboBoxItemTemplate defines how each item in the dropdown list is shown. It binds to the Name property, so when the ComboBox is opened, the user sees a list of names (e.g., "item 1", "item 2", etc.).
<DataTemplate x:Key="ComboBoxItemTemplate">
<Grid>
<TextBlock Width="40" Text="{Binding Name}" />
</Grid>
</DataTemplate>
Selected Item Template (Icon Display): The SelectedItemIconTemplate defines how the selected item is displayed when the ComboBox is collapsed. It binds to the Icon property of the selected item and displays it as an icon.
<DataTemplate x:Key="SelectedItemIconTemplate">
<Grid>
<fluentIcons:SymbolIcon
Width="16"
Height="16"
Symbol="{Binding Icon}" />
</Grid>
</DataTemplate>
ControlTemplate for ComboBox: The ComboBoxControlTemplate customizes the entire ComboBox control, including how the selected item is shown (only the icon) and how the dropdown list is presented.
<ControlTemplate x:Key="ComboBoxControlTemplate" TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
ClickMode="Press"
Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter
Name="ContentSite"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{StaticResource SelectedItemIconTemplate}"
IsHitTestVisible="False" />
</ToggleButton>
<Popup
Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True">
<Border BorderBrush="Black" BorderThickness="1">
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
Note on Content="{TemplateBinding SelectionBoxItem}": This TemplateBinding links the ContentPresenter to the SelectionBoxItem property of the ComboBox. SelectionBoxItem represents the currently selected item, which is displayed when the ComboBox is collapsed. By using this binding, the ContentPresenter dynamically shows the selected item's content, while the ContentTemplate ensures it is formatted correctly (e.g., as an icon).
Applying the Templates to the ComboBox: Finally, we apply these templates to the ComboBox in the UI. The ItemTemplate defines how each item in the list appears, and the Template specifies the overall control behavior.
<ComboBox
Height="30"
ItemTemplate="{StaticResource ComboBoxItemTemplate}"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Template="{StaticResource ComboBoxControlTemplate}" />