Every element in your application provides a Resources property (this includes every control and container), which is actually a Dictionary in which the key is a string, and the value is a resource. In other words, every element contains a collection of resources, indexed by a string key name.
Although every element can contain its own defined resources, most of the time it’s easiest to place resources at the window level. Doing that makes the available to all the controls in the window. Every element always has access to all its resources, and the resources of its parents (all the way back up to the application level), so if you want to share resources between elements, the higher you place the resources, the easier it will be to do so.
Imagine that you want to create a LinearGradientBrush instance that you will use as the background for several controls on a page. Rather than defining it in the content of each individual element, you can extract the gradient in the resources collection for the container (in this example, a user control) instead. The sample user control, IntroResource.xaml, includes a very simple resource. The syntax in the sample (displayed in Figure 1) looks like the following:
TIP: Although the examples here are all based on user controls for the purposes of making the demonstration easier to navigate, you can also define resources at any level. Often, in WPF applications, you’ll define resources at the window level, in the Window.Resources element.
The differences between this definition and what you would see if you had defined the gradient brush for each individual element are:
- The resource appears inside the UserControl.Resources element.
- The resource includes an x:Key attribute, defining the key for the resource. Remember that the collection of resources is actually a Dictionary, and every item in a dictionary must contain a unique key that identifies it.
NOTE The x: prefix on the Key attribute indicates that it’s in the XAML namespace, rather than the WPF namespace. You’ll use this key to refer to the resource, whenever you want to use it. It doesn’t matter what you call the resource, as long as you use this Key attribute value to refer to the resource.
TIP: Name your resources based on their functionality, not their contents. The uses won’t change as often as the particular implementation details, and it will be easier to select resources if you name them based on their usage.
To use the resource, you must be able to refer to it. To do this, use a markup extension, delimited with curly braces:
You may have seen the markup extension syntax used when performing property binding, or in other contexts. In general, XAML uses markup extensions whenever it needs to be able to set a property in a non-standard way. In this case, the StaticResource keyword indicates that when XAML needs to retrieve and set the Background property of the Border element, it
should look for a resource whose x:Key attribute is BackgroundBrush, and use
the definition it finds there.
Would you use a resource in a case like this, in which you only consume the resource once? It certainly doesn’t make the XAML any more efficient, or more compact. On the other hand, it does make it easier to isolate the layout details—by placing all the formatting information in one place, it’s easier to keep track of, and maintain, the look of your application.
You may be wondering about the word “Static” in the markup extension. Why Static? Is there a Dynamic resource, as well? WPF provides both static resources, which are applied only once, when you first create the window, and dynamic resources, which are reapplied if the resource changes. Dynamic resources (using the DynamicResource markup extension) use slightly more overhead, but allow you to change the content of the resource at runtime. Static resources are simpler, and provide much of the functionality you’ll need.
NOTE If you programmatically change a feature of an existing static resource at runtime (for example, if you change a color, or some other property of the existing resource), WPF automatically updates the display to match. Dynamic resources allow you to replace the entire resource with another at runtime. In general, static resources provide the functionality you’ll need for most applications.
WARNING! It’s important that you define the static resources before you attempt to use them in the markup. Unlike most modern programming languages, the order of appearance within the source file is a concern—you cannot use a resource before it has been declared. The XAML parser reads content from start to finish, and expects to find the definition for a resource at the time the XAML attempts to use the resource. This isn’t true for dynamic resources, however. You can define dynamic resources after they’re used, and the XAML parse can still find them.
This post is an excerpt from the online courseware Presentation Foundation Using Visual C# 2010 course written by expert Ken Getz and Robert Green.
Ken Getz is a Visual Studio expert with over 25 years of experience as a successful developer and consultant. He is a nationally recognized author and speaker, as well as a featured instructor for LearnNowOnline.
Robert Green is a Visual Studio expert and a featured instructor for several of our Visual Basic and Visual C# courses. He is currently a Technical Evangelist in the Developer Platform and Evangelism (DPE) group at Microsoft. He has also worked for Microsoft on the Developer Tools marketing team and as Community Lead on the Visual Basic team. Robert also has several years of consulting experience focused on developer training, and is a frequent speaker at technology conferences including TechEd, VSLive, VSConnections and Advisor Live.