Dynamically binding to a logical resource
As we saw in the previous recipe, Using logical resources, binding to a resource is achieved in XAML by using the StaticResource
markup extension. But what happens if we replace a specific resource? Would that be reflected in all objects using the resource? And if not, can we bind to the resource dynamically?
Getting ready
Make a copy of the previous recipe project CH02.SimpleResources
, or create a new project named CH02.DynamicVsStatic
and copy the Window XAML contents from the previous project to the new one.
How to do it...
We'll replace StaticResource
with DynamicResource
and see the effect:
- Open
MainWindow.xaml
. Add a button to the end of theStackPanel
labeled Replace brush and connect it to an event handler namedOnReplaceBrush
. This is the added markup:<Button Content="Replace brush" Click="OnReplaceBrush" />
- In the event handler, we'll replace the brush resource named
brush1
with a completely new brush:void OnReplaceBrush(object sender, RoutedEventArgs e) { var brush = new RadialGradientBrush(); brush.GradientStops.Add(new GradientStop(Colors.Blue, 0)); brush.GradientStops.Add(new GradientStop(Colors.White, 1)); this.Resources["brush1"] = brush; }
- Run the application and click on the button. You'll notice nothing happens. Now change the
StaticResource
markup extension toDynamicResource
on theRectangle
:<Rectangle Height="100" Stroke="Black" Fill="{DynamicResource brush1}" />
- Now run the application and click on the button. You'll see the
Fill
property ofRectangle
has changed to the new resource value:
How it works...
The DynamicResource
markup extension binds to a resource dynamically, which means that if the object itself is replaced with a new object (with the same key), the new resource is used. StaticResource
bound properties keep referencing the old object.
This dynamic behavior allows for interesting effects. For instance, themes can be changed by swapping resources as long as the keys are the same.
There's more...
The StaticResource
markup extension causes binding to the resource to occur at construction time (in the call to InitializeComponent
of the Window
). DynamicResource
, on the other hand, is only bound when actually needed. This means that DynamicResource
is a bit faster at Window
load time, while consuming (naturally) more resources, as it needs to be notified when the resource is replaced.
Also, DynamicResource
does not throw an exception if the key does not exist. If that key appears later, it will bind to the resource correctly.
StaticResource
should be used most of the time unless there is a need to replace resources on the fly, in which case DynamicResource
should be used.