Szymon Kobalczyk's Blog

A Developer's Notebook

  Home  |   Contact  |   Syndication    |   Login
  84 Posts | 5 Stories | 164 Comments | 380 Trackbacks

News

View Szymon Kobalczyk's profile on LinkedIn

Twitter












Article Categories

Archives

Post Categories

Image Galleries

Blogs I Read

Tools I Use

After working with WPF for a while I must say that it is wonderful platform for building complex user interfaces but sometimes it falls short in very simple scenarios. Or in other words, it's easy to do complex things with it's powerful tools but often it lacks simple tools to do simple things. At least from a perspective of Windows Forms developer who expects some familiar tools and quickly finds out that they are gone.

There are several examples of this, but one that I run across recently and find it very often in other forums is how to change default colors in more complex controls like ListBox or ComboBox. For example yesterday there was a question on the MSDN forum on how to change the highlight color in a popup of combobox.

All controls in WPF have only three properties to adjust their colors: Foreground, Background and BorderBrush (keep in mind that all of these properties accept brushes instead of solid colors). But you won't find such properties as HighlightedItemBrush on ComboBox or SelectedItemBrush on ListBox.

I read somewhere, that primary reason for this is that Controls encapsulate logical elements and shouldn't have properties that depend on their visual representation. Instead the appearance of each control is defined through it's ControlTemplate and with some alternative template these properties might make no sense at all.

So it might seem that the only option to override these colors would be to recreate the ControlTemplate for particular control and adjust the colors. Thankfully you don't have to do it manually. With Microsoft Expression Blend you can very easily create copy of the default ControlTemplate by selecting the control and then from menu invoking Object > Edit Control Parts (Template) > Edit a Copy...

But this will only recreate the template for your current Windows Theme so if you have to preserve all other visual aspects of the control you need to put even more work to subclass your control and recreate all themes for the new control. This is quite a big effort to do such a small thing.

There is however much simpler solution if overriding the default colors is the only thing you want to change. Because these colors are defined as resources you can try to override these resource for your control.

For example, to change the color of selected item in a ListBox (or highlighted item in ComboBox ) override following resource:

<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Orange" />

And because I also wanted to have the same color when ListBox doesn't have focus I needed to override this resource as well:

<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Orange" />

As with all resources you can do it either only for this particular control (using Style.Resources), whole window or even for the whole application depending on which ResourceDictionary you would use. And because these resources are referenced as DynamicResource you can even adjust them at runtime.  

So now the only problem is to find out what resources you need to override to get the desired control. Once again the Microsoft Expression Designer comes in handy and you can find this out by recreating the default templates but this time only to read what colors it uses and what what purpose.

I've started putting together a reference of which system colors are used in default templates for simple controls and will publish it shortly.

posted on Sunday, March 25, 2007 1:46 PM

Feedback

# re: Overriding default SystemColors in WPF 4/10/2007 4:52 PM felixthehat
hi there - yeah it took me ages to work out how to do this too, and I came to the same conclusions. Did you work out a way to control the foreground colour too? eg If I wanted the highlight colour to be black and the text to be white?

thanks!

# re: Overriding default SystemColors in WPF 4/10/2007 7:38 PM Szymon
I was trying to put together a list of standard colors and how are thay affect various controls but this is just to many of them. I only did a list of standard colors for reference:
http://geekswithblogs.net/images/geekswithblogs_net/kobush/1591/o_XPBlue.png

You can use the above method to override also the Foreground for ListBoxes (and for many other controls), by assigning new value to the WindowTextBrushKey.

# re: Overriding default SystemColors in WPF 4/17/2007 9:37 AM felixthehat
Cool - useful list, thanks! Although the color ref I was after I believe is HighlightTextBrush - although according to MSDN the HighlightTextBrush: "This brush's IsFrozen property is true, so it cannot be modified." - try this example here:

<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00ABDF" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrush}" Color="#FFFFFFFF" />

I can't believe that it's possible to change the background highlight and not the foreground!



# re: Overriding default SystemColors in WPF 4/25/2007 7:28 AM bk
i totally agree with felixthehat.
it's a great pity that the styling concept isn't really realized continuously. i really don't know what the benefit of these styling technique should be if cannot alter certain properties of my 'look'.

# re: Overriding default SystemColors in WPF 7/6/2007 10:41 AM Maria
Ovveride "HighlightTextBrushKey" property to change the foreground color on selected item.

Hope it helps.


# re: Overriding default SystemColors in WPF 5/14/2008 6:13 PM Top
How to override the color of the selection menu? I try on MenuHighlightbrush but it does nothing. Do you have any suggestion?

# re: Overriding default SystemColors in WPF 5/29/2008 5:22 PM E. Tom Jorgenson
Hmmm. I'm puzzled. I tried using this technique to override the system colors (and nothing else) within a theme and the theme doesn't seem to do anything. Am I correct in assuming that these overrides will replace the system colors without being referenced in a template in the theme?

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 7 and 7 and type the answer here: