DeCaf
DeCaf

Reputation: 6116

Define a color as a system color within a theme in WPF

I want to define a SolidColorBrush as a resource in my WPF application (or rather in an assembly that several applications may refer to).

In some themes I want this color to be explicitly defined in the resource dictionary making up the theme, but in for example the classic theme I want this color to be a system color.

For example:

Aero.NormalColor.xaml:

   <SolidColorBrush 
      x:Key="{ComponentResourceKey 
         TypeInTargetAssembly={x:Type l:MyClass},
         ResourceId=MyColor}" 
         Color="#FF3399FF"/>

Classic.xaml:

   <SolidColorBrush 
      x:Key="{ComponentResourceKey 
         TypeInTargetAssembly={x:Type l:MyClass},
         ResourceId=MyColor}" 
         Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}"/>

This brush should then be available to my application by the name MyColor so that it can be re-defined on a theme level. If defined as above everything works as it should when the color is defined as a literal (i.e. when using the Aero theme), but when referring to the SystemColors dynamic resource (in Classic.xaml) I get an exception saying "This freezable can not be frozen" during application startup. (At least if I have several of these brushes defined, it seems to work in some scenarios, such as when using only a single color, but it doesn't seem very stable anyway.

Edit: The usage would then be something like:

<Border Background="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type l:MyClass}, ResourceId=MyColor}}">

It does not seem to be all to easy to reproduce. When I just created a theme file with two of these colors, and an empty Window with the line above in a Grid the program runs, but the designer within Visual Studio instead throws the exception above. Not quite sure how to create a minimal example that reproduces this in runtime.

So how can I prevent this error from occurring, or what method should I be using to achieve my goal here?

Upvotes: 1

Views: 1608

Answers (1)

Uzzy
Uzzy

Reputation: 550

Do you realy need dynamic link to system color? Did you try set Static resource? I mean change

Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}

to

Color="{StaticResource {x:Static SystemColors.HighlightColorKey}}

Does it make sense?

Seems it is by design: http://www.vistax64.com/avalon/263-freezable-can-not-frozen-dynamicresource-x-static-systemcolors-controldarkdarkcolorkey.html

Upvotes: 2

Related Questions