Windows Presentation Foundation 4.5 Cookbook
上QQ阅读APP看书,第一时间看更新

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:

  1. Open MainWindow.xaml. Add a button to the end of the StackPanel labeled Replace brush and connect it to an event handler named OnReplaceBrush. This is the added markup:
        <Button Content="Replace brush" 
           Click="OnReplaceBrush" />
  2. 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;
    }
  3. Run the application and click on the button. You'll notice nothing happens. Now change the StaticResource markup extension to DynamicResource on the Rectangle:
      <Rectangle Height="100" Stroke="Black" 
                 Fill="{DynamicResource brush1}" />
  4. Now run the application and click on the button. You'll see the Fill property of Rectangle has changed to the new resource value:
    How to do it...

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.