1

What is the most direct way to set the ComboBoxItem highlight color using a ComboBox style?

For example, I would like to be able to write something like:

<my:ExtendedComboBox ItemBackgroundHighlight="Green" />
<my:ExtendedComboBox ItemBackgroundHighlight="Red" />

And have each ComboBox have the corresponding color for its mouseover/selected highlight.

Edit

As I might have guessed, there is a simple way to do this in WPF, which however is not possible in Silverlight.

Community
  • 1
  • 1
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • If you're already using a custom template for the `ComboBox` I would just find the object(s) supplying that visual currently when they're activated by the VisualStateManager for MouseOver/Selected states, bind its `Background` or `Fill` or whatever to an adhoc property like `Tag` at the Template level like `{TemplateBinding Tag}` and do `` etc. Posted as comment instead of answer since I dont immediately have much time to put much thought into it. – Chris W. May 09 '14 at 19:35
  • @ChrisW. thanks ... the tricky thing about this is that, since the `ComboBoxItem` is a separate control, there seems to be no easy way to pass a property (ItemBackgroundHighlight) from the parent ComboBox to the child ComboBoxItems. In my answer below, I solved this problem by applying a binding from parent to child in "GetContainerForItemOverride". – McGarnagle May 09 '14 at 20:01
  • Ah right, ya I've got to quit trying to speed through these things without thinking them through at a glance. Glad you found a remedy though, cheers – Chris W. May 10 '14 at 16:08

1 Answers1

3

This is the simplest solution I could come up with.

First, subclass ComboBoxItem, add a dependency property Brush BackgroundHighlight and modify its control template (this is necessary because the highlight color is hard-coded to "#FFBADDE9" in the default control template). Only 2 lines in the control template need to be changed, "#FFBADDE9" to "{TemplateBinding BackgroundHighlight}":

<Rectangle x:Name="fillColor" Fill="{TemplateBinding BackgroundHighlight}" IsHitTestVisible="False" Opacity="0" RadiusY="1" RadiusX="1"/>
<Rectangle x:Name="fillColor2" Fill="{TemplateBinding BackgroundHighlight}" IsHitTestVisible="False" Opacity="0" RadiusY="1" RadiusX="1"/>

Second, subclass ComboBox and add the Brush ItemBackgroundHighlight dependency property. Also, override the "GetContainerForItemOverride" method, returning the subclassed ComboBoxItem and binding its "BackgroundHighlight" property to the parent "ItemBackgroundHighlight" property.

protected override DependencyObject GetContainerForItemOverride()
{
    var container = new ExtendedComboBoxItem();
    var highlightBinding = new Binding
    {
        Source = this,
        Path = new PropertyPath(ItemBackgroundHighlightProperty),
    };
    container.SetBinding(ExtendedComboBoxItem.BackgroundHighlightProperty, highlightBinding);
    return container;
}

And that's it. I can now write simply:

<my:ExtendedComboBox ItemBackgroundHighlight="Green" />
<my:ExtendedComboBox ItemBackgroundHighlight="Red" />

The colors show on mouseover and selection:

Styled combo boxes

Note: make sure to set the DefaultStyleKey properties as follows. This way, the modified control template will be applied to the ExtendedComboBoxItems, while the default template will be applied to the ExtendedComboBox.

  • on ExtendedComboBox: DefaultStyleKey = typeof(ComboBox)
  • on ExtendedComboBoxItem: DefaultStyleKey = typeof(ExtendedComboBoxItem)
McGarnagle
  • 101,349
  • 31
  • 229
  • 260