views:

39

answers:

2

Hi,

Just wondering if anyone knows how to change the look of the button on a wpf combobox? In case you are wondering I just want to change the shape of it and the background.

Thanks.

+1  A: 

Use control templates for that.

codymanix
Well how do you use them?
Michael Lockwood
They are quite complicated. you should start with pulling out the default control template of the standard combobox using a tool like XamlPadX and then modify the control template.
codymanix
+2  A: 

You can easily modify the ControlTemplate or style of controls using Expression Blend.

Here is one example which will use the Simple Style for the ComboBox and i have modified the Toggle button Color to red.

  <LinearGradientBrush x:Key="NormalBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#EEE" Offset="0.0"/>
        <GradientStop Color="#CCC" Offset="1.0"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="NormalBorderBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#CCC" Offset="0.0"/>
        <GradientStop Color="#444" Offset="1.0"/>
    </LinearGradientBrush>

    <!-- LightBrush is used for content areas such as Menu, Tab Control background -->
    <LinearGradientBrush x:Key="LightBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFF" Offset="0.0"/>
        <GradientStop Color="#EEE" Offset="1.0"/>
    </LinearGradientBrush>

    <!-- MouseOverBrush is used for MouseOver in Button, Radio Button, CheckBox -->
    <LinearGradientBrush x:Key="MouseOverBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFF" Offset="0.0"/>
        <GradientStop Color="#AAA" Offset="1.0"/>
    </LinearGradientBrush>

    <!-- PressedBrush is used for Pressed in Button, Radio Button, CheckBox -->
    <LinearGradientBrush x:Key="PressedBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#BBB" Offset="0.0"/>
        <GradientStop Color="#EEE" Offset="0.1"/>
        <GradientStop Color="#EEE" Offset="0.9"/>
        <GradientStop Color="#FFF" Offset="1.0"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="PressedBorderBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#444" Offset="0.0"/>
        <GradientStop Color="#888" Offset="1.0"/>
    </LinearGradientBrush>

    <!-- SelectedBackgroundBrush is used for the Selected item in ListBoxItem, ComboBoxItem-->
    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD"/>

    <!-- Disabled Brushes are used for the Disabled look of each control -->
    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888"/>
    <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>
    <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA"/>

    <!-- Used for background of ScrollViewer, TreeView, ListBox, Expander, TextBox, Tab Control -->
    <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF"/>

    <!-- DefaultedBorderBrush is used to show KeyBoardFocus -->
    <LinearGradientBrush x:Key="DefaultedBorderBrush" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#777" Offset="0.0"/>
        <GradientStop Color="#000" Offset="1.0"/>
    </LinearGradientBrush>

    <SolidColorBrush x:Key="SolidBorderBrush" Color="#888"/>
    <SolidColorBrush x:Key="LightBorderBrush" Color="#AAA"/>
    <SolidColorBrush x:Key="LightColorBrush" Color="#DDD"/>

    <!-- Used for Checkmark, Radio button, TreeViewItem, Expander ToggleButton glyphs -->
    <SolidColorBrush x:Key="GlyphBrush" Color="#444"/>

    <Style x:Key="test" TargetType="{x:Type ComboBox}">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBox}">
                <Grid>
                    <!-- The ToggleButton is databound to the ComboBox itself to toggle IsDropDownOpen -->
                    <ToggleButton Grid.Column="2" Template="{DynamicResource ToggleButtonControlTemplate1}" x:Name="ToggleButton" Focusable="false" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
                    <ContentPresenter HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="ContentSite" VerticalAlignment="Center" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" IsHitTestVisible="False"/>

                    <!-- The TextBox must be named PART_EditableTextBox or ComboBox will not recognize it -->
                    <TextBox Visibility="Hidden" Template="{DynamicResource ComboBoxTextBox}" HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="PART_EditableTextBox" Style="{x:Null}" VerticalAlignment="Center" Focusable="True" Background="Transparent" IsReadOnly="{TemplateBinding IsReadOnly}"/>

                    <!-- The Popup shows the list of items in the ComboBox. IsOpen is databound to IsDropDownOpen which is toggled via the ComboBoxToggleButton -->
                    <Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" x:Name="Popup" Focusable="False" AllowsTransparency="True" PopupAnimation="Slide">
                        <Grid MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}" x:Name="DropDown" SnapsToDevicePixels="True">
                            <Border x:Name="DropDownBorder" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="{DynamicResource SolidBorderBrush}" BorderThickness="1"/>
                            <ScrollViewer Margin="4,6,4,6" Style="{DynamicResource SimpleScrollViewer}" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">

                                <!-- The StackPanel is used to display the children by setting IsItemsHost to be True -->
                                <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>

                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <!-- This forces the DropDown to have a minimum size if it is empty -->
                    <Trigger Property="HasItems" Value="false">
                        <Setter Property="MinHeight" Value="95" TargetName="DropDownBorder"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger Property="AllowsTransparency" SourceName="Popup" Value="true">
                        <Setter Property="CornerRadius" Value="4" TargetName="DropDownBorder"/>
                        <Setter Property="Margin" Value="0,2,0,0" TargetName="DropDownBorder"/>
                    </Trigger>
                    <Trigger Property="IsEditable" Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <Setter Property="Visibility" Value="Visible" TargetName="PART_EditableTextBox"/>
                        <Setter Property="Visibility" Value="Hidden" TargetName="ContentSite"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<ControlTemplate x:Key="ToggleButtonControlTemplate1" TargetType="{x:Type ToggleButton}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="20"/>
        </Grid.ColumnDefinitions>
        <Rectangle Grid.ColumnSpan="2" HorizontalAlignment="Stretch" x:Name="Rectangle" VerticalAlignment="Stretch" Width="Auto" Height="Auto" RadiusX="5" RadiusY="5" Fill="{DynamicResource NormalBrush}" Stroke="{DynamicResource NormalBorderBrush}"/>
        <Rectangle Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" RadiusX="5" RadiusY="5" Fill="{DynamicResource WindowBackgroundBrush}" Stroke="{DynamicResource NormalBorderBrush}"/>
        <Path Grid.Column="1" HorizontalAlignment="Center" x:Name="Arrow" VerticalAlignment="Center" Fill="Red" Data="M 0 0 L 4 4 L 8 0 Z"/>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Fill" Value="{DynamicResource MouseOverBrush}" TargetName="Rectangle"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
            <Setter Property="Fill" Value="{DynamicResource PressedBrush}" TargetName="Rectangle"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Fill" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Rectangle"/>
            <Setter Property="Stroke" Value="{DynamicResource DisabledBorderBrush}" TargetName="Rectangle"/>
            <Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}"/>
            <Setter Property="Fill" Value="{DynamicResource DisabledForegroundBrush}" TargetName="Arrow"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

To change the Shape or background of the Toggle Button in the example you have to modify the ControlsTemplate "ToggleButtonControlTemplate1".

Kishore Kumar