Overview Of WPF Resources

Resources in WPF are the sets of objects like Brushes, Templates, styles etc. which are stored in a dictionary and referenced by unique strings. Usually, they are declared once and used throughout the application. They are like CSS (Cascading Style Sheets) used in styling web pages.

Why Resources?

While working on large scale WPF applications, there are some aspects that developers want consistent throughout the applications, like theme or styles of application, for example, Button background color.

  1. <Button Background="DodgerBlue"/>  

In large-scale applications, there are going to be hundreds of buttons and maintaining background color for all of them individually is a difficult task. A developer may miss out on some while updating them. That’s why developers use resources where they can declare resource once and then reference throughout the application.

Resources Basics

Each element in WPF can have its own collection of resources. Collection of the resources is stored in ‘Resources’ property of each element. This ‘Resource’ property is derived from ‘FrameworkElement’. ‘Resource’ property stores resources in dictionary format where you can add any type of object identified by a unique string (like a key).

Declaring Resources

Declare resources in <Element.Resource> markup with ‘key’ attribute.

In the following example, we declare two ‘SolidColorBrush’ objects in ‘Resources’ collection of ‘Windows’ element

  1. <Window.Resources>  
  2.     <SolidColorBrush x:Key="blueBrushResource" Color="Blue" />  
  3.     <SolidColorBrush x:Key="redBrushResource" Color="Red" />  
  4. </Window.Resources>  

Referencing Resources

To reference resource for any property, we can use markup extensions called ‘StaticResource’ or ‘DynamicResource’. To explain the usage, we will use ‘StaticResource’ and later explain the difference between them. In both markup extensions we must pass ‘key’ attribute of the resource we want to use.

In the following example, we set the background property of both buttons by referencing the resources through ‘StaticResources’ markup extension.

  1. <Button Content="Blue Button" Background="{StaticResource blueBrushColor}"/>  
  2. <Button Content="Red Button" Background="{StaticResource redBrushColor}"/>  
Hierarchy of Resources

Each element has a collection of their own resources. Also, resources can be declared at different levels like Windows, Application etc. In that scenario how does WPF resolve resource references?

WPF resolves resource references by looking for them in their own collection. If it didn’t find it then it moves up the element tree until it finds the resource.

In the previous example, WPF will look for the resource in the Button’s own collection where it does not find it. Then it moves up the element tree and looks for Window’s resource collection. Let’s assume WPF does not find resources in Window’s resource collection. Then it will move to Application resource collection.

In the below example, the third button in Stack Panel will take the local resource and other buttons will take resource from Window’s resource collection.

Note
You can give the same key to the resource if they are in different scopes (i.e., different collections). In the example below, two resources have the same key as ‘blueBrushColor’. But since they are in a different resource collection, WPF doesn’t throw an exception or error.

  1. <Window.Resources>  
  2.     <SolidColorBrush x:Key="blueBrushColor" Color="Blue" />  
  3.     <SolidColorBrush x:Key="redBrushColor" Color="Red" />  
  4. </Window.Resources>  
  5. <StackPanel>  
  6.     <Button Content="Blue Button" Background="{StaticResource blueBrushColor}" />  
  7.     <Button Content="Red Button" Background="{StaticResource redBrushColor}" />  
  8.     <Button Content="Dodger Blue">  
  9.         <Button.Resources>  
  10.             <SolidColorBrush x:Key="blueColorBrush" Color="DodgerBlue" />  
  11.         </Button.Resources>  
  12.         <Button.Background>  
  13.             <StaticResource ResourceKey="blueColorBrush" />  
  14.         </Button.Background>  
  15.     </Button>  
  16. </StackPanel>  
Static and Dynamic Resources

When we use ‘StaticResource’ markup extension WPF grabs the object from resource collection and uses it. If you make any changes to the retrieved object it won’t be reflected in UI.

In the case of ’DynamicResoources’ markup extension, WPF looks up an object in resource collection every time it is needed. Meaning you always get a fresh copy of an object. Changes made to that object from code behind will automatically be reflected.

XAML

  1. <Window.Resources>  
  2.     <SolidColorBrush x:Key="drBrushColor" Color="DarkRed" />  
  3. </Window.Resources>  
  4. <Button Name="btnDynamicResource" Content="Dynamic Resource" Background="{DynamicResource drBrushColor}" Click="btnDynamicResource_Click" />  

CODE BEHIND

  1. private void btnDynamicResource_Click(object sender, RoutedEventArgs e) {  
  2.     Resources["drBrushColor"] = new SolidColorBrush(Colors.Green);  
  3. }  

In XAML button uses resource from Window’s collection as a Dynamic Resource. When we click the button click event basically changes resource value which will be reflected in the UI immediately since we are using the resource as a Dynamic resource. In the case of Static Resource, the changes won’t be reflected.

Nonshared Resources

Normally when you refer to a resource, the object is shared across all the references. But in some cases, you don’t want to share resources. In that case, you can declare that resource as a Nonshared resource.

  1. <SolidColorBrush x:Key="drBrushColor" Color="DarkRed" x:Shared="false"/>  
Application Resources

So far, we have seen resources at the local level and Windows level (Container level). But WPF does not stop look up if it does not find a resource. It starts looking for resources defined at the application level. As the name suggests these resources are available to the entire application. Thus, developers define resources at application level only if they are used throughout the application frequently; for example, Theme or Toolbar color.

Resource Dictionary

Application resources make resources available for the entire application. But what if developers want to share resources across the entire project? In that case, Resource Dictionaries are used. A resource dictionary is a plain XAML which includes only resources.

Resource dictionary can be added to your project by merging it with any resources. But standard practice is to add it to the application level.

To merge Resource Dictionary with each other and with Resources, you must create ‘ResourceDictionary’ markup and then, add all resources and merge all dictionaries as follows.

  1. <ResourceDictionary>  
  2.     <ResourceDictionary.MergedDictionaries>  
  3.         <ResourceDictionary Source="WizardBrushes.xaml" />  
  4.     </ResourceDictionary.MergedDictionaries>  
  5.     <SolidColorBrush x:Key="blueBrushColor" Color="Blue" />  
  6.     <SolidColorBrush x:Key="redBrushColor" Color="Red" />  
  7.     <SolidColorBrush x:Key="drBrushColor" Color="DarkRed" x:Shared="false" />  
  8. </ResourceDictionary>  
WPF Resources