Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF StaticResource works, DynamicResource doesn't

I have been trying for a day now, to no avail, to create a bunch of brushes in the theme then using them with DynamicResource in a custom control. What I did is this:

  • create the theme generic.xaml which contains styles (works)
  • add a dictionary to merge in generic.xaml to contain brushes used in the application (works)
  • make brushes have ComponentResourceKey keys (works)
  • make control use brushes as static resource (works)
  • make control use brushes as dynamic resource (DOESN'T WORK, the resource trace source says as much: System.Windows.ResourceDictionary Warning: 9 : Resource not found; )
  • add in App.Resources dynamically a brush with the same key (works with dynamic resource, it changes the colors, doesn't work with static resource, as expected)

So my problem is that I can't find any way to define the default values in the theme so that I can change them programatically in the application. How can StaticResource find the brush and DynamicResource not?!

I must add that I've created a static class holding the component resource keys as properties that I then use in the xaml as {x:Static UI:ResourceScheme.ControlBackgroundKey} for example. My problem seems similar to this one: ComponentResourceKey as DynamicResource problem only that if I replace the static property keys to the XAML markup for component resource key, it still doesn't work.

Can someone please help me out here? :(

like image 692
Siderite Avatar asked Aug 21 '10 09:08

Siderite


People also ask

What is the difference between static resource and dynamic resource in WPF?

WPF - StaticResource vs DynamicResource. The difference between StaticResource and DynamicResource lies in how the resources are retrieved by the referencing elements. StaticResource are retrieved only once by the referencing element and used for entire life of the resource. On the other hand,DynamicResource are acquired every time...

What is the difference between staticresource and dynamicresource in Java?

The difference between StaticResource and DynamicResource lies in how the resources are retrieved by the referencing elements. StaticResource are retrieved only once by the referencing element and used for entire life of the resource. On the other hand,DynamicResource are acquired every time the referenced object is used.

Is it possible to define dynamicresource in XAML?

You can define DynamicResource in XAML as well, but it will resolve at runtime only. I hope this article has cleared your confusion between static and dynamic resources in WPF. Please apply them to achieve reusability in your projects.

What is the XAML key for staticresource?

This key was initially assigned by the x:Key Directive if a resource was created in markup, or was provided as the key parameter when calling ResourceDictionary.Add if the resource was created in code. A StaticResource must not attempt to make a forward reference to a resource that is defined lexically further within the XAML file.


2 Answers

Here is the difference,

StaticResource loads at time of loading, this means that the resource key that you are using, must be lexically defined before the usage.

So, static resource in case of custom control must be defined only above the control definition in the same generic.xaml file. So if you put your brushes in different xaml, it will certainly not work in case of static resource.

This is the reason, unless the other resources of type xaml is included in the form of some sort of import at a time of complile in same file, you can not use static resource in the file. It simply means that the file/component/control's actual xaml some how should contain actual reference of static resource you use.

Now I have my doubt of why DynamicResource will not work, that is because probably DynamicResource will only look in the Application's (where the control is use) ResourceDictionary but not generic.xaml.

I am not 100% sure but I feel if you define a custom control and if you use DynamicResource then your resources has to be in the Application's Resource Dictionary or the parent container of your control's resource dictionary, but it can not be in generic.xaml.

Because DynamicResource will only look up for keys in the logical tree of control's runtime and thats why it may not find resources that are in generic.xaml unless generic.xaml is explicitly added in Application.Resources.

Summary: StaticResource must be available lexically before in the same file at compile time, resources will be available in Application.Resources dictionary, it still can find in logical tree but at a compile time only in the same dll or same generic.xaml.

DynamicResource must will be searched in Application.Resources and in the logical tree of the control at runtime.

For more reference, please check Resources Overview

like image 86
Akash Kava Avatar answered Sep 20 '22 05:09

Akash Kava


Finally fixed it. It appears that having the type for the component resource key in another assembly caused the whole issue. Let me summarize:

  • there is a resource class that holds the ComponentResourceKeys as static properties. The type used in the constructor of the resource keys is the type of this class. This is in the Resources assembly.
  • there is a theme for the custom controls in another assembly, the Controls assembly, that defines some brushes using as key the properties of the resource class: {x:Static Namespace:ResourceClass.ResourceKeyProperty}
  • in the same theme, templates for controls use the brushes as dynamic resources: {DynamicResource {x:Static Namespace:ResourceClass.ResourceKeyProperty}}
  • there is also an application that uses these controls and that dynamically adds custom brushes in the application resources. These brushes have the same keys as the ones in the theme.

The end result for this is:

  • the controls do not use the brushes initially
  • the controls do use the brushes added in the application resources
  • the controls use the brushes initially if StaticResource is used in the theme, but then the application resources are ignored

The solution for this seems to be to move the resources class in the controls library.

As I still do not know why this is happening, this question remains open, even if slightly changed: why doesn't it work in the first scenario?

like image 34
Siderite Avatar answered Sep 17 '22 05:09

Siderite