The term resource has a very broad meaning—in WPF, any object can be a resource. A brush or a color used in various parts of a user interface could be a resource. Snippets of graphics or text can be resources. An object does not have to do anything special to qualify as a resource. The resource handling infrastructure is entirely dedicated to making it possible to get hold of the resource you require, and it doesn't care what the resource is. It simply provides a mechanism for identifying and locating objects.
At the heart of resource management is the ResourceDictionary class. Outwardly, this is just a simple collection class. It behaves much like an ordinary Hashtable—it allows objects to be associated with keys, and it provides an indexer that lets you retrieve those objects using these keys. So, in theory, you could use the ResourceDictionary like a Hashtable, as Example 12-1 shows.
Example 12-1. Naïve ResourceDictionary programming
ResourceDictionary myDictionary = new ResourceDictionary(); myDictionary.Add("myBrush", Brushes.Green); myDictionary.Add("HW", "Hello, world");
In practice, you will not often create your own ResourceDictionary in this way. Instead, you will normally use ones provided by WPF. For example, the FrameworkElement base class, from which most user interface elements derive, provides a resource dictionary in its Resources property. The calls to Add in Example 12-1 illustrate the usual way to add resources from code-behind files, but this dictionary can also be populated from markup, as Example 12-2 shows.
Example 12-2. Populating a ResourceDictionary from XAML
<Window x:Class="ResourcesExample.Window1" Title="Resources" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib">
<Window.Resources> <SolidColorBrush x:Key="myBrush" Color="Green" /> <s:String x:Key="HW">Hello, world</s:String> </Window.Resources>
<Grid x:Name="myGrid"> </Grid> </Window>
The x:Key attribute specifies the key that identifies the resource in the dictionary. It is equivalent to the first parameter of the calls to Add in Example 12-1. You can use any object as a key. Strings are the most common choice, although distinct object instances are often used to identify very broadly scoped resources, such as system resource.
When you use compiled XAML to populate a resource dictionary, WPF defers creation of the resources. It leaves each resource in its serialized form (known as BAML), and expands this into real objects only on demand. This can significantly improve the startup time for a user interface in cases where not all of the objects are needed as soon as the UI appears. For the most part, this optimization will not have any direct effect on your code's behavior other than speeding it up. However, if there is something wrong with your markup, this deferred creation can cause the resulting errors to emerge later than you might have expected.
Example 12-3 shows code retrieving the resources defined in Example 12-2.
Example 12-3. Retrieving resources from an element's ResourceDictionary the wrong way
// NOT the best way to retrieve resources Brush b = (Brush) this.Resources["myBrush"]; String s = (String) this.Resources["HW"];
This code accesses the ResourceDictionary using this.Resources. This is all very well for the code-behind file for the markup that defined the resources. However, it is not always this convenient to get hold of the right dictionary. What if we want to define resources accessible to all windows in the application? It would be both tedious and inefficient to copy the same resources into every window in the application. And what if we want a custom control to pick up resources specified by its parent window, rather than baking them into the control? To solve these problems, and to make it easy to achieve consistency across your user interface, FrameworkElement extends the basic ResourceDictionary facilities with a hierarchical resource scope.
Was this article helpful?
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.