Geeks With Blogs

News
View Szymon Kobalczyk's profile on LinkedIn

Szymon Kobalczyk's Blog A Developer's Notebook

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 Development , WPF | Back to top


Comments on this post: Overriding default SystemColors in WPF

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
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!
Left by felixthehat on Apr 10, 2007 4:52 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
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.
Left by Szymon on Apr 10, 2007 7:38 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
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!

Left by felixthehat on Apr 17, 2007 9:37 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
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'.
Left by bk on Apr 25, 2007 7:28 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Ovveride "HighlightTextBrushKey" property to change the foreground color on selected item.

Hope it helps.
Left by Maria on Jul 06, 2007 10:41 AM

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

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
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?
Left by E. Tom Jorgenson on May 29, 2008 5:22 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Hi,
The above code for overriding the system colors work fine in xaml.
Can you help me how to achieve the same functionality in C# Code (not using Xaml). I want to set it runtime without using style

thanks
Left by sejal on Feb 04, 2009 10:51 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Hi Sejal
To answer your question - doing this from C#;

Style s = new Style(typeof(ListView));
s.Resources.Add(SystemColors.HighlightBrushKey, Brushes.Red);
list.Style = s;

where list is of type ListView
Left by mk on Sep 07, 2009 10:44 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
I may sound really stupid.. but I am very new to WPF ...
I jus wanted to know how to use this statement

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

i hv added this in windows.resource block then how to use on menu control so tht it take the value..

I would really appreciate if u send some demo code how to set this properties n use it.

thanks
Left by Shivangi on Mar 24, 2010 10:08 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
ohh...silly of me...i figured it how to style it...
Thanks a lot
Left by shivangi on Mar 24, 2010 12:11 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Hi, From MSDN only I got your this blog url. I want to set the background and foreground of a Combobox when an item is highlighted. As you suggested, I have used :
<ComboBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">Red</SolidColorBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}">White</SolidColorBrush>
</ComboBox.Resources>
tried with ControlBrushKey in place of HighlightTextBrushKey, but the text color doesn't change to White. It stays as gray only.
I also want to change the mouse over control for Combobox - Please refer http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9700318e-75e7-4222-9c53-f4256146c3c6 for detailed.
What am I lacking in changing the text color of the text of item.
Left by Trupti on Oct 04, 2011 4:05 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Hi,
I don't know where I can override it. Is that possible please upload a sample file or specify the complete code?

Thanks
Left by Smart on Jan 24, 2012 4:41 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Hi, Nice & Precise article. you saved lot of time. Thanks.
Left by pravin sawant on Dec 28, 2013 2:20 AM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
Your link is broken
http://geekswithblogs.net/images/geekswithblogs_net/kobush/1591/o_XPBlue.png
I would love to see the list of those common resources, its hard to find them.
Left by Adam on Jun 23, 2014 5:59 PM

# re: Overriding default SystemColors in WPF
Requesting Gravatar...
shivangi since you worked it out you could've said how instead of just "oh i figured it out"
Left by adam on Jul 24, 2017 1:52 PM

Your comment:
 (will show your gravatar)


Copyright © Szymon Kobalczyk | Powered by: GeeksWithBlogs.net