Szymon Kobalczyk's Blog

A Developer's Notebook

  Home  |   Contact  |   Syndication    |   Login
  106 Posts | 6 Stories | 541 Comments | 365 Trackbacks

News

View Szymon Kobalczyk's profile on LinkedIn

Twitter












Tag Cloud


Article Categories

Archives

Post Categories

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?

# re: Overriding default SystemColors in WPF 2/4/2009 10:51 AM sejal
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

# re: Overriding default SystemColors in WPF 9/7/2009 10:44 AM mk
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

# re: Overriding default SystemColors in WPF 3/24/2010 10:08 AM Shivangi
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


# re: Overriding default SystemColors in WPF 3/24/2010 12:11 PM shivangi
ohh...silly of me...i figured it how to style it...
Thanks a lot

# re: Overriding default SystemColors in WPF 10/4/2011 4:05 PM Trupti
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.

# re: Overriding default SystemColors in WPF 1/24/2012 4:41 PM Smart
Hi,
I don't know where I can override it. Is that possible please upload a sample file or specify the complete code?

Thanks

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: