I have SolidColorBrush and DrawingImage (vector icon) as XAML resources, both on a global level, in Application.Resources. DrawingImage have GeometryDrawing inside which uses aforesaid brush as DynamicResource.
Looks like this:
<SolidColorBrush x:Key="brushPrimaryColor"/>
<DrawingImage x:Key="iconMain">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{DynamicResource brushPrimaryColor}"/>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
It is working initially, but changing (swapping for new brush) brushPrimaryColor at a runtime does not reflect on iconMain. DrawingImage is also used as DynamicResource, not frozen and i can change it directly in code.
Basically what i want is to make changeable palette from few brushes for set of vector icons. Is it possible to do with resources, or should i copy resource at a runtime and bind to that copy instead?
CodePudding user response:
Most resources that extend Freezable
and are defined in the App.xaml ReeourceDictionary
are frozen by default (by the XAML engine). For example, brushes defined in the global ResourceDictionary
(App.xaml) are expected to be shared across the application. In other words, the name scope of App.xaml is global and resources with the same resource key cannot appear at a different node in the resource tree (they are unique). It's safe to assume that App.xaml resources are shared. Therefore, to improve performance the XAML engine will freeze every Brush
defined in App.xaml, based on the assumption that Brush
resources will be treated like static resources.
To change this behavior, you must explicitly instruct the XAML engine to not share this kind of resources. You do this by setting the x:Shared
attribute to false
. This way the XAML engine will not assume that resources are referenced as static resource and thus will not freeze the Freezable
resource.
As mentioned before the default behavior is that the XAML parser will share resources. The x:Shared
attribute therefore defaults to true
.
To solve your issue, set x:Shared
on the resource to false
:
App.xaml
<!-- Prevent global Brush from being frozen by the XAMK engine
by setting x:Shared to False -->
<SolidColorBrush x:Key="brushPrimaryColor"
x:Shared="False" />
<DrawingImage x:Key="iconMain">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{DynamicResource brushPrimaryColor}"/>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>