Resource References

So far, we have seen how to retrieve the current value of a named resource in code. Because we usually use resource values to set element properties, we will now look at how to set an element's property to the value of a resource. This may seem like a ridiculously trivial step. You might expect it look like Example 12-13.

Example 12-13. How not to use a system resource value this.Background = (Brush) this.FindResource(SystemColors.ControlBrushKey);

This is fine for some resource types, but here it will work only up to a point—it will successfully set the Background property to a brush that paints with whatever the currently selected color for control backgrounds is at the moment when this line of code runs. However, if the user changes the system color scheme, this Background property will not be updated automatically. The code in Example 12-13 effectively takes a snapshot of the resource value.

The code in Example 12-14 does not suffer from this problem. Instead of taking a snapshot, it associates the Background property with the resource.

Example 12-14. Self-updating system resource reference this.SetResourceReference(Window.BackgroundProperty, SystemColors.ControlBrushKey);

Unlike Example 12-13, if the system resource value changes, the property will automatically receive the new value. The practical upshot of this is that if the user changes the color scheme using the Display Properties Control Panel applet, Example 12-14 will ensure that your user interface is updated automatically.

WPF defines markup extensions that are the XAML equivalent of the code in the previous two examples. (See Appendix A for more information on markup extensions.) These are the StaticResource and DynamicResource extensions. If you are using a system resource, or any other resource that might change at runtime, choose DynamicResource. If you know the resource will never change, use StaticResource, which takes a snapshot, avoiding the costs associated with tracking the resource for changes. (The cost is small, but you may as well avoid it for resources that never change.) Example 12-15 shows the use of both resource reference types.

Example 12-15. Using resources from markup

<Window x:Class="ResourcesExample.Window2" Title="Resources" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Window.Resources>

<SolidColorBrush x:Key="myBrush" Color="LightGreen" /> </Window.Resources>

<Grid Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">

<TextBlock FontSize="36" Width="200" Height="200"

Background="{StaticResource myBrush}">Hello!</TextBlock>

A StaticResource reference must appear after the resource to which it refers. Forward references are not allowed.

The top-level Window defines a brush as a resource named myBrush. The TextBlock uses this for its Background property via a StaticResource reference. This has a similar effect to the code in Example 12-13. It takes a snapshot, and is appropriate for resources that will not change while the application runs.

The grid's Background has been set to the system "control" color. (This is typically battleship gray—the color often used as the background for dialogs.) Because this is a user-configurable color and could therefore change at runtime, we've used a DynamicResource, which has the same effect as the call to SetResourceReference in Example 12-14.

The DynamicSource syntax is a little more complex than for the StaticResource. This complexity is not because we are using DynamicResource. It is because the resource we wish to use is identified by an object, returned by the static SystemColors. ControlBrushKey property. We could have tried this:

<Grid Background="{DynamicResource SystemColors.ControlBrushKey}">

This is syntactically correct, but doesn't do what we want. It will be interpreted as a dynamic reference to a resource named by the string SystemColors.ControlBrushKey. There is no such resource, so the background will not be set. To use the real resource key (the object returned by the ControlBrushKey static property), we have to use the x:Static markup extension as Example 12-15 does—this tells the XAML compiler that the text should be treated as the name of a static property, not as a string.

Was this article helpful?

0 0
Project Management Made Easy

Project Management Made Easy

What you need to know about… Project Management Made Easy! Project management consists of more than just a large building project and can encompass small projects as well. No matter what the size of your project, you need to have some sort of project management. How you manage your project has everything to do with its outcome.

Get My Free Ebook


Post a comment