1

I have used Styles and ControlTemplate to change the appearance of the ComboBox and ComboBoxItem. Now The final appearance is as below.

enter image description here

Now what I want is to somehow change the template of the ComboBoxItem so that it looks like below. I don't want the instructions on how to draw the colored rectangles. Just how to create the two-column template and how to update it.

enter image description here

Here is the code I have used to achieve the first image:

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />


<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
    <Rectangle x:Name="Border" Width="188" Height="23" Fill="{StaticResource NormalImg}"></Rectangle>
    <ControlTemplate.Triggers>

        <Trigger Property="ToggleButton.IsChecked" Value="true">
            <Setter TargetName="Border" Property="Fill" Value="{StaticResource PressedImg}" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border" Property="Fill" Value="{StaticResource NormalImg}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
    <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>

<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="UseLayoutRounding" Value="True"></Setter>
    <Setter Property="TextOptions.TextFormattingMode" Value="Display"></Setter>
    <Setter Property="Foreground" Value="White"></Setter>
    <Setter Property="FontSize" Value="11"></Setter>
    <Setter Property="RenderOptions.ClearTypeHint" Value="Enabled"></Setter>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="MinWidth" Value="188"/>
    <Setter Property="MinHeight" Value="23"/>
    <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">
                    </ToggleButton>
                    <ContentPresenter
    Name="ContentSite"
    IsHitTestVisible="False" 
    Content="{TemplateBinding SelectionBoxItem}"
    ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
    ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
    Margin="7,0,0,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="{StaticResource WindowBackgroundBrush}"
        BorderThickness="1"
        BorderBrush="{StaticResource SolidBorderBrush}"/>
                            <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 SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,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"/>
                        <Setter Property="Foreground" Value="#FFFFFF"></Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="UseLayoutRounding" Value="True"></Setter>
    <Setter Property="TextOptions.TextFormattingMode" Value="Display"></Setter>
    <Setter Property="RenderOptions.ClearTypeHint" Value="Enabled"></Setter>
    <Setter Property="Foreground" Value="Black"></Setter>
    <Setter Property="FontSize" Value="11"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <Border 
    Name="Border"
    Padding="2"
    SnapsToDevicePixels="true" TextOptions.TextFormattingMode="Display">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsHighlighted" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#FFFFFF"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<ComboBox Width="188" Height="23" Margin="0 1 0 0" Style="{StaticResource ComboBoxStyle}">
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Model</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Columns Layout</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Column Elevations</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Column Sections</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Beams Layout</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Beam Elevations</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}">Floors Layout</ComboBoxItem>
</ComboBox>
Vahid
  • 5,144
  • 13
  • 70
  • 146

1 Answers1

2

Here is the easiest solution to use the Tag property.

<ComboBox Width="188" Height="23" Margin="0 1 0 0" Style="{StaticResource ComboBoxStyle}">
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="10">Model</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="20">Columns Layout</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="30">Column Elevations</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="40">Column Sections</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="50">Beams Layout</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="60">Beam Elevations</ComboBoxItem>
    <ComboBoxItem Style="{StaticResource ComboBoxItemStyle}" Tag="70">Floors Layout</ComboBoxItem>
</ComboBox>

Then update your ComboBoxItemStyle Template.

<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem">
    <!-- other code omitted -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <Border  Name="Border" Padding="2" SnapsToDevicePixels="true" TextOptions.TextFormattingMode="Display">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="20" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <ContentPresenter Grid.Column="0" />
                        <ProgressBar Grid.Column="2" Value="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" Maximum="100" Width="100"></ProgressBar>
                    </Grid>
                </Border>
                <!-- other code omitted -->
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

PS: The expected UI might not really close to what you want, but it will give you idea where to start.

Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67
  • Thank you so much Yuliam, this is actually a genius idea to do it like this. But when I select an item and close the popup I also want the image to be displayed in the combobox area. – Vahid Jul 19 '14 at 16:58
  • @Vahid, you need to also modify the ComboBox Template :) – Yuliam Chandra Jul 19 '14 at 17:03
  • Can you please tell me where should I change. I'd be very grateful, I tried but I failed. – Vahid Jul 19 '14 at 17:04
  • @Vahid, [here](http://msdn.microsoft.com/en-us/library/ms752094%28v=vs.110%29.aspx) copy paste the default template and start figuring out where to put the grid :) – Yuliam Chandra Jul 19 '14 at 17:05
  • Thanks Yuliam, I'll try from the scratch. Just one more thing that I noticed. When we change the controltemplate of the combobox like this, it seems that it gets a bit slow when the mouse pointer is moving through its items. Have you noticed that too? – Vahid Jul 19 '14 at 17:09
  • 1
    @Vahid, yup I noticed, maybe the Binding selector to Tag is not efficient, or maybe it took time to cast object to integer, ideally create a custom data context for each combo box itme – Yuliam Chandra Jul 19 '14 at 17:13
  • custom datacontext for each combobox? Then I'll need to change the style too? I'm really lost :( – Vahid Jul 19 '14 at 17:19
  • perhaps adjusting the style too, check [this](http://stackoverflow.com/questions/561166/binding-wpf-combobox-to-a-custom-list) how to bind combo box – Yuliam Chandra Jul 19 '14 at 17:23
  • Thanks Yuliam, I'll try the articles you gave me and if needed I'll start a bounty for the complete answer in two days. – Vahid Jul 19 '14 at 17:26