Click here to Skip to main content
13,249,813 members (66,781 online)
Click here to Skip to main content
Add your own
alternative version


7 bookmarked
Posted 16 Nov 2007

Fixing WPF ComboBox Colors Without Extending or Templating

, 16 Nov 2007
Rate this:
Please Sign up or sign in to vote.
This article demonstrates a very simple technique which can be used to easliy modify the standard Windows Presentation Foundation controls without creating an extended class or using a data template.


If you have worked with WPF and used a non-standard color scheme, you may have run into a problem with ComboBoxes or other WPF controls. I was using a dark color scheme with White text. However, the ComboBoxes in my application ignored the foreground setting in the style. The only way I could get the ComboBox foreground to change was to explicitly set it for each ComboBox. ComboBox styling in WPF was broken.

I tried different techniques to fix the problem, which all required more code than I liked:

  • First attempt: Extend the ComboBox class with my own class that hides the foreground properties and set them manually. This worked, but it required me to use a different class name everywhere in my XAML code and in the style's TargetType.
  • Second attempt: Create a data template that contained a ComboBox and set the colors manually. This did not work, as the data template's foreground was never set.
  • Final attempt: Listen to the Foreground Dependency Property's Changed event (actually a callback) and fix the colors there. This worked! And it required no changes to any ComboBox declarations.


The first two combo boxes have not changed the foreground color, while the second set are correct.

The background color of the drop down is still White.

The background color of the drop down matches the background color.

Using the Code

Here is the important class that does all the work:

public static class ComboBoxFix
  private static bool _isInitialized = false;

  /// <summary>
  /// Initialize must be called 
  /// before any Combo boxes are created
  /// </summary>
  public static void Initialize()
    if( !_isInitialized )
      // Registed the callback methods 
      // when the properties change on a ComboBox class
          typeof( ComboBox ),
          new FrameworkPropertyMetadata( OnBackgroundChanged ) );

          typeof( ComboBox ),
          new FrameworkPropertyMetadata( OnForegroundChanged ) );

      _isInitialized = true;

  private static void OnBackgroundChanged( 
    DependencyObject d, DependencyPropertyChangedEventArgs e )
    // Set the drop down background color to match the background
    SetDropDownBackground( d as ComboBox );

  private static void OnForegroundChanged( 
    DependencyObject d, DependencyPropertyChangedEventArgs e )
    // Manually set the foreground (to overcome bug)
    // Apparently the ComboBox does not listen 
    // when the Foreground DepencyProperty
    // is changed and therefore does not 
    // update itself unless the value is changed 
    // through the Foreground .net property
    (d as ComboBox).Foreground = e.NewValue as Brush;

  private static void SetDropDownBackground( ComboBox comboBox )
    // The drop down control uses 
    // the WindowBrush to paint its background
    // By overriding that Brush (just for this control)

    if( comboBox.Resources.Contains( SystemColors.WindowBrushKey ) )
      comboBox.Resources.Remove( SystemColors.WindowBrushKey );

      SystemColors.WindowBrushKey, comboBox.Background );

The Intialize method must be called before any ComboBoxes are created. The best place to put the ComboBoxFix.Iniatilize() call is on the first line of the main window's constructor.

Points of Interest

The Dependency Property system is very powerful. With very little code, it is possible to register to the Changed events of all objects of a specific type that contain that property.

However, it is more complex than a standard .NET property. It is important to remember that WPF binding, animations, etc., set the Dependency Property directly. They do not go through the .NET property setter.

It seems that the source of this problem is related to this difference.

Therefore, if you create any Dependency Properties, remember to handle the changes to that value by registering a callback method in the property metadata.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralInteresting approach. Pin
Patrick Sears16-Nov-07 11:20
memberPatrick Sears16-Nov-07 11:20 
I hadn't thought of approaching it this way. I wonder if some of our other WPF gurus would have something to say about this.. in some sense it seems to violate the templating approach intended in WPF. But maybe I'm wrong.

It has become appallingly obvious that our technology has exceeded our humanity. - Albert Einstein

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 16 Nov 2007
Article Copyright 2007 by CoderForChrist
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid