1

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?

DeCaf
  • 6,026
  • 1
  • 29
  • 51
  • `DynamicResource` is likely not compatible with freezing. – user7116 May 07 '13 at 19:18
  • You need do some stuff with Freaazable objects. You may find a walkaround here: http://stackoverflow.com/questions/799890/how-can-wpf-objects-deriving-from-freezable-be-frozen-in-xaml – Uzzy May 07 '13 at 03:25
  • I've tried with the `po:Freeze="True"` (and `False` for that matter) with no difference. So unfortunately that does not seem to help. – DeCaf May 07 '13 at 15:56
  • Can you show the usage of your color? – Uzzy May 07 '13 at 16:00
  • updated the question with some more info. – DeCaf May 07 '13 at 19:16

1 Answers1

2

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

Uzzy
  • 550
  • 3
  • 14
  • I thought I needed a DynamicResource so that colors would update when the theme changed. But after testing your suggestion it seems that the colors do indeed update if the windows theme is changed when the application is running anyway... with the added bonus that now it doesn't throw an exception of course ;) – DeCaf May 08 '13 at 20:08