BlackWaspTM
Windows Presentation Foundation
.NET 4.0+

WPF Resources

The one hundred and forty-seventh part of the Windows Presentation Foundation Fundamentals tutorial looks at resources. These allow the reuse of shared items, such as styles, templates, type converters and many other objects.

Resources

So far in the WPF tutorial we've created many sample projects. Some of these included repetitive elements, such as groups of similarly formatted elements, each with its styling set explicitly through a number of properties. When creating a large application, this type of repetition is problematic. Firstly, it is dull for the developer and prone to error. Secondly, any change to the repeated item must be manually replicated throughout the solution.

The solution to the problem of repetition is to encourage reuse of components such as styles, templates, value converters and data. WPF provides a means to achieve reuse through resources. Resources are simply objects, generally defined using XAML, that can be shared between elements of the software.

To demonstrate the use of resources, we need a sample solution. Create a new WPF application in Visual Studio named, "ResourcesDemo". Once the solution is ready, replace the XAML in the main window with the following code:

<Window x:Class="ResourcesDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Resources Demo" Height="200" Width="300">
    <UniformGrid>
        <Ellipse>
            <Ellipse.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="Cyan" Offset="0.2"/>
                        <GradientStop Color="LightBlue" Offset="0.4"/>
                        <GradientStop Color="White" Offset="0.5"/>
                        <GradientStop Color="White" Offset="0.6"/>
                        <GradientStop Color="DarkGray" Offset="0.6"/>
                        <GradientStop Color="Black" Offset="0.8"/>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Ellipse.Fill>
        </Ellipse>

        <Ellipse>
            <Ellipse.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="Cyan" Offset="0.2"/>
                        <GradientStop Color="LightBlue" Offset="0.4"/>
                        <GradientStop Color="White" Offset="0.5"/>
                        <GradientStop Color="White" Offset="0.6"/>
                        <GradientStop Color="DarkGray" Offset="0.6"/>
                        <GradientStop Color="Black" Offset="0.8"/>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Ellipse.Fill>
        </Ellipse>

        <Ellipse>
            <Ellipse.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="Cyan" Offset="0.2"/>
                        <GradientStop Color="LightBlue" Offset="0.4"/>
                        <GradientStop Color="White" Offset="0.5"/>
                        <GradientStop Color="White" Offset="0.6"/>
                        <GradientStop Color="DarkGray" Offset="0.6"/>
                        <GradientStop Color="Black" Offset="0.8"/>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Ellipse.Fill>
        </Ellipse>

        <Ellipse>
            <Ellipse.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Color="Cyan" Offset="0.2"/>
                        <GradientStop Color="LightBlue" Offset="0.4"/>
                        <GradientStop Color="White" Offset="0.5"/>
                        <GradientStop Color="White" Offset="0.6"/>
                        <GradientStop Color="DarkGray" Offset="0.6"/>
                        <GradientStop Color="Black" Offset="0.8"/>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
    </UniformGrid>
</Window>

This rather repetitive XAML generates a window containing four Ellipses. Each is filled with the same linear gradient brush.

WPF Resources Demo Window

Defining a Resource

You can define resources against any control or user interface element using its Resources property, which is defined in the FrameworkElement base class. The property holds a ResourceDictionary object. A resource dictionary provides a keyed collection of objects, each of which can be referenced from the control or its logical children using a special markup syntax.

As resources are available to the control that defines them, and to all of its children, it is common to define the resource dictionary against the root element of the XAML. Let's create a resource for the linear gradient brush using the Window's Resources property. Amend the Window opening tag, as follows:

<Window x:Class="ResourcesDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Resources Demo" Height="200" Width="300">
    <Window.Resources>
        <LinearGradientBrush x:Key="BlueSky" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStop Color="Cyan" Offset="0.2"/>
                <GradientStop Color="LightBlue" Offset="0.4"/>
                <GradientStop Color="White" Offset="0.5"/>
                <GradientStop Color="White" Offset="0.6"/>
                <GradientStop Color="DarkGray" Offset="0.6"/>
                <GradientStop Color="Black" Offset="0.8"/>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
    </Window.Resources>

You can see that the Resources property is added using property element syntax. Each resource is created using a new child within the resource dictionary element. In this case, we have a single LinearGradientBrush resource. You must define a unique key for the resource to enable it to be found by controls that reference it. In the sample XAML, the key is set to "BlueSky" using the x:Key attribute.

29 March 2015