Show selected item in ComboBox with custom item template

14,034

Solution 1

You can define ItemTemplate for ComboBox instead of ControlTemplate for ComboBoxItem to achieve that. As you can see, ControlTemplate for ComboBoxItem doesn't affect selected item appearance when ItemTemplate does. Following is content of your CustomComboboxItem Style merged within ComboBox Style :

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
        ........
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid>
                        <Grid.Style>
                            <Style TargetType="Grid">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="LightGray"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Grid.Style>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                            <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                        </Grid>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        ........
    </Style>

Solution 2

You should override toString() method of CustomComboboxItem class.

Share:
14,034

Related videos on Youtube

Wenjo
Author by

Wenjo

Updated on June 04, 2022

Comments

  • Wenjo
    Wenjo almost 2 years

    I used the code from this page to style my combobox: How to style ComboBox Background on Mouse Hover?

    I've changed my default item template, but now they won't appear in the selected value area. In the image below you can see the problem and what I want to achieve.

    Screenshot showing desired effect

    This is my XAML in App.xaml:

    <LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientStop Offset="0" Color="#FFF3F3F3"/>
        <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
    </LinearGradientBrush>
    
    <LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientStop Offset="0" Color="#FFF3F3F3"/>
        <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
    </LinearGradientBrush>
    
    <LinearGradientBrush x:Key="ButtonBackgroundHoverBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientStop Offset="0" Color="#FFE4E4E4"/>
        <GradientStop Offset="0.3" Color="#FFBBBBBB"/>
    </LinearGradientBrush>
    
    <LinearGradientBrush x:Key="ButtonBackgroundDisabledBrush" StartPoint="0,0" EndPoint="0,1">
        <GradientStop Offset="0" Color="#FF636363"/>
        <GradientStop Offset="0.3" Color="#FF4E4D4D"/>
    </LinearGradientBrush>
    
    <SolidColorBrush x:Key="GlyphBrush" Color="#FFF" />
    
    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
    
    <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
    
    <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="20" />
            </Grid.ColumnDefinitions>
    
            <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="{StaticResource ButtonBackgroundBrush}" BorderBrush="#FF898989" BorderThickness="1" />
            <Border x:Name="Border2" Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="White" BorderBrush="#FF898989" BorderThickness="0,0,1,0" />
    
            <Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource GlyphBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="ToggleButton.IsMouseOver" Value="True">
                <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
                <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
                <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
            </Trigger>
            <Trigger Property="ToggleButton.IsChecked" Value="True">
                <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
                <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
                <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundDisabledBrush}" />
                <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    
    <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
        <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
    </ControlTemplate>
    
    <Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
        <Setter Property="MinWidth" Value="120"/>
        <Setter Property="MinHeight" Value="20"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBox">
                    <Grid>
                        <ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
                        <ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
                        <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
                        <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
                            <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <Border x:Name="DropDownBorder" Background="White" BorderThickness="1" BorderBrush="#FF898989" />
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasItems" Value="False">
                            <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                        </Trigger>
                        <Trigger Property="IsGrouping" Value="True">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                        </Trigger>
                        <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
                            <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,2,2"/>
                            <Setter TargetName="DropDownBorder" Property="Margin" Value="0,-1,0,0"/>
                        </Trigger>
                        <Trigger Property="IsEditable" Value="True">
                            <Setter Property="IsTabStop" Value="False"/>
                            <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <Style x:Name="CustomComboboxItem" TargetType="ComboBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBoxItem">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                            <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                        </Grid>
                    </Grid>
    
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="LightGray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    MainWindow.xaml:

    <ComboBox Height="40" HorizontalAlignment="Left" Margin="102,64,0,0" Name="comboBox1" VerticalAlignment="Top" Width="459" />
    

    Code-behind:

    public MainWindow()
    {
        InitializeComponent();
    
        comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 1", NewItemComment = "hello :)" });
        comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 2", NewItemComment = "hello :)" });
        comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 3", NewItemComment = "hello :)" });
        comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 4", NewItemComment = "hello :)" });
        comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 5", NewItemComment = "hello :)" });
    }
    
    public class CustomComboboxItem
    {
        public string NewItemName { get; set; }
        public string NewItemComment { get; set; }
    }
    

    Can someone tell me what I'm doing wrong?

  • Wenjo
    Wenjo about 10 years
    Still the same.. @Sankarann
  • Wenjo
    Wenjo about 10 years
    Still nothing @Sankarann
  • Wenjo
    Wenjo about 10 years
    Where do i do that? In App.xaml, MainWindow.xaml or MainWindow.xaml.cs? @Sankarann