2

I would like to customize the default - "OnMouseOver"-"color" for the Combobox and also the "Background" color for the list that drops down in the combobox ..can we customize the above mentioned properties of combobox..If yes, please help me.. the following is my Xaml code for the combobox :

<ComboBox Name="CmbBox1" BorderBrush="Black" Margin="1,1,1,1"
                      ItemsSource="{Binding}">
                <ComboBox.Style>
                    <Style TargetType="{x:Type ComboBox}">
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="Red"/>
                        </Trigger>
                        </Style.Triggers>
                    </Style>
                </ComboBox.Style>
                    <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Background="{Binding Background}" Foreground="Black" FontSize="10"  TextAlignment="Left" 
                                               FontWeight="Black" Text="{Binding}"></TextBlock>

                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
soma sekhar
  • 259
  • 2
  • 5
  • 15

1 Answers1

2

Here is one way to do what I think you're after. I made a few changes to your ComboBox.

Added comments in the Xaml code so it should be pretty self explanatory

Edit. This didn't work under Windows 7 because of the ButtonChrome that is deep within the ComboBox Template. You could either re-template the whole thing, or use this workaround which uses some code behind.

First, add a reference to PresentationFramework.Aero
Then subscribe to the Loaded event of the ComboBox and disable the ButtonChrome and bind the MainGrid background in the event handler like this

private void CmbBox1_Loaded(object sender, RoutedEventArgs e)
{
    ComboBox comboBox = sender as ComboBox;
    ToggleButton toggleButton = GetVisualChild<ToggleButton>(comboBox);
    ButtonChrome chrome = toggleButton.Template.FindName("Chrome", toggleButton) as ButtonChrome;
    chrome.RenderMouseOver = false;
    chrome.RenderPressed = false;
    chrome.RenderDefaulted = false;
    chrome.Background = Brushes.Transparent;
    Grid MainGrid = comboBox.Template.FindName("MainGrid", comboBox) as Grid;
    Binding backgroundBinding = new Binding("Background");
    backgroundBinding.Source = comboBox;
    MainGrid.SetBinding(Grid.BackgroundProperty, backgroundBinding);
}

private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
    T child = default(T);
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
            break;
        }
    }
    return child;
}

Xaml

<ComboBox Name="CmbBox1" BorderBrush="Black" Margin="1,1,1,1"
          ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"
          Loaded="CmbBox1_Loaded"
          Width="150">
    <ComboBox.Resources>
        <SolidColorBrush x:Key="MouseOverBrush"
                         Color="Red"/>
        <SolidColorBrush x:Key="DropDownListBrush"
                         Color="Green"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                         Color="Transparent"/>
    </ComboBox.Resources>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBox}},
                                                Path=IsDropDownOpen}"
                             Value="True">
                    <Setter Property="Background" Value="{StaticResource DropDownListBrush}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.ItemContainerStyle>
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource MouseOverBrush}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Border x:Name="border" SnapsToDevicePixels="True">
                <TextBlock Foreground="Black" FontSize="10"  TextAlignment="Left" 
                           FontWeight="Black" Text="{Binding}"></TextBlock>
            </Border>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBoxItem}}, Path=IsMouseOver}" Value="True">
                    <Setter TargetName="border" Property="Background" Value="{StaticResource MouseOverBrush}"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • Thank you..the above code could change the dropdown-background for the combobox..However, It could not change the default mouseover-color for the combobox control..please let me know if there is a way out for resolving it.. – soma sekhar Aug 23 '11 at 15:09
  • @soma sekhar: How do you mean? It changes the `Background` for the selected item when you hover it with your mouse. Was it something else you were after? – Fredrik Hedblad Aug 23 '11 at 15:15
  • @soma sekhar: Updated my answer with a complete Xaml example. Just copy/paste that as it is and it should give you the desired behavior. Otherwise I missunderstood the question somehow – Fredrik Hedblad Aug 23 '11 at 15:21
  • My bad.. I tested this on XP. Now when I try it on Windows 7 I can see the problem.. The problem is the Chrome in the Template, I'll update my answer – Fredrik Hedblad Aug 23 '11 at 15:49
  • @soma sekhar: Try the updated answer and see if that workaround works :) – Fredrik Hedblad Aug 23 '11 at 16:12
  • @some sekhar: Weird, it should be. Uploaded my sample application here: http://www.mediafire.com/?21y4m9cgwa9ad4n – Fredrik Hedblad Aug 24 '11 at 12:08
  • thanks.. its working..I have declared the background color of the listbox in the tag itself..so its been overwriting the applied styles..so, I have made the changes for that..it worked out..another thing is that, once we have an item selected in the combobox and then if we go for selecting another one from the popdown list..we have the background color for the selected item in the combobox as Green....rather being Red..which I think, not so nice to view..please let me know if any possibilities to reslove.. – soma sekhar Aug 24 '11 at 12:54
  • @some sekhar: Updated my answer, see if it works the way you like – Fredrik Hedblad Aug 24 '11 at 13:24
  • hi..Meleak..am unable to follow the code that's been used for "combobox_loaded" event and the "GetVisualChild" method...Could you please explain me the actual thing that's being carried out in the "Combobox_Loaded" event and "GetVisualChild" method as mentioned in the above code....Thank you.. – soma sekhar Sep 05 '11 at 12:49
  • A `ComboBox` has a `ToggleButton` as a child in the Visual Tree and a `ToggleButton` uses `ButtonChrome` inside its Template. When the Mouse is over the `ComboBox`, RenderMouseOver is set to true for the `ButtonChrome` trough a Trigger which overrides any `Background` we try to set. When we get the `ButtonChrome` in the `Loaded` event handler for the `ComboBox` we set its local value for `RenderMouseOver` to `false` (`chrome.RenderMouseOver = false`). Local value has higher priority then Triggers so the Trigger will be unable to change the value anymore. – Fredrik Hedblad Sep 05 '11 at 13:12
  • You can have a look at the later part of my answer to this question for the full priority list for Dependency Properties if you're interested: http://stackoverflow.com/questions/7137291/how-does-the-wpf-dependency-property-design-save-memory-consumption – Fredrik Hedblad Sep 05 '11 at 13:14