Published: 05 Nov 2007
By: Brian Mains
Download Sample Code

This article will show how to use Styles, Resources, and Control Templates in WPF.

Resources

Resources store reference to an object within a collection. For instance, most objects in the WPF framework have a Resources collection. The Application object, Window, Button, and other WPF controls all have a Resources collection. A resource can be anything, such as a Brush to use for painting the background, a control template (which we'll look at later), or many other types of objects. Below is an example of a brush defined in the windows resource collection.

In the previous example, the Window defines a gradient brush with a key of BlueButtonBackground. The background can be referenced using the BlueButtonBackground key like so:

StaticResource is an extension that is used to reference items defined in a resource collection. If not found in the immediate element's resource collection (the button's), it navigates up the stack until it can find the resource with that key. If the button resides in a StackPanel control - which resides in a Grid - the resource will be sought for in the button first, StackPanel second, Grid third, Window fourth, and so on. Resources can contain anything, and the last section on Control Templates will illustrate how the control template itself will be defined and referenced as a resource.

Resources can also be stored in a central place, such as a resource dictionary. A resource dictionary is a collection of resources that can be easily incorporated into an application. They can be used to contain a single reference to all the assemblies in a single or multiple applications. The following is a simple resource dictionary.

To include a resource dictionary in a Window or user control, include the following definition:

The referenced resource dictionary is now included in the user control, and any resources are automatically applied.

Styles

With ASP.NET 2.0 came a feature called themes. Themes had the ability to set styles to the inner style properties of a control. Any property that defined a ThemeableAttribute with a constructor value of true could assign that property in the skin file, using the same markup as the control (for the most part). Styles do not have the same markup as themes do, but the approach is the same.

A style can set the inner properties of a XAML element using setters, as will be illustrated soon. We can define event triggers, which are styles that are applied when an event occurs. An even more useful approach is to use a style trigger, which applies itself whenever a target condition is evaluated to true. For instance, it is possible to change the background color and foreground color whenever a button is pressed, and then revert back to the original setting when that event is false. This works because of the change notification that elements provide when the value exposed by a property changes.

An example style is shown below:

This style is defined in the Window's Resources collection. The style is given a key, so it can be uniquely referenced. A series of setters can be defined in order to specify which properties will be changed. In the example above, only two setters are defined, but you could have continued on with many more entries. In the following example, the style changes the background property to a gradient brush. To use this style, the following code defines a static resource extension and embeds it in a control's background:

In this situation, a style is applied to a button. But it doesn't have to be; it could be applied to many types of elements. Suppose that the only target for this style was a button; using a different property, we can apply it to only buttons:

In this situation, the style is applied to all buttons, depending on where it is defined (if in the application, Window, resource dictionary, or local resource collection). TargetType looks for any instance of a button and applies the appropriate style. With this approach, the Control prefix on the setter property is no longer needed.

Triggers can be used for styles as well. For instance, a button has several properties it can use to determine what state it is in. It has an IsPressed property that is used to determine whether a mouse button is currently pressed, an IsEnabled property that determines if the button is enabled, an IsFocused property for determining whether the control has focus (such as when tabbing through the controls on a form), and many more. Each of these properties can be used in a style trigger to perform some action. Take the definition below:

Upon pressing the button, the background changes from a lighter gradient to a darker one. This happens because the control has its own change notification. When the button is pressed, the "swap is made". Triggers require that the comparison is an equality comparison. A trigger can't be used to determine if a property is within a specific range. Rather, it often checks if a value matches its condition exactly.

Styles also have the ability to inherit from each other, by specifying the key of another style in the BasedOn attribute. The following is a style that inherits from another style. All of the base styles are applied, and additional ones are defined in the new style shown below.

As you can see, style inheritance is easy to do.

Control Templates

Each control has a base template that it uses to render its user interface. This interface is a template and is instantiated whenever the control is displayed. The control itself is made up of a lot of different parts; but often includes styles and style triggers, and utilizes resources in several ways.

A control template is actually an element that one can define in a resources collection, or in a resource dictionary. The following declaration is perfectly valid:

To use this template, a button must be declared as follows:

Using this approach, the following template can add a rounded corner border to a button control. In addition, the button has an inner white square border, and includes a commonly-used text statement at the top.

Our button has a rounded corner border consisting of blue colors. Note the ContentPresenter declaration; this declaration allows the inner content of the button to be bound inside the control. So the text "Templated Button" is rendered inside the templated button.

Styles can be used to apply a control template. For example, it is possible to apply a style template using the following style (note that the style is still set the same way, by applying it through the Style property).

In addition, a template can be applied automatically, simply by using the TargetType attribute on a style. The following applies the control template to all buttons:

A button can ignore this style by manually applying a style with the {x:Null} property value.

Summary

Resources and styles are great ways to modify the basic appearance of a .NET application. Control templates still rely on these capabilities to provide a stellar user interface. Resources provide an excellent way to define certain objects in a global location, and resource dictionaries provide a way to make resources available at a global scale. Styles are really dynamic in their ability to set property values, because they can listen to property changes and apply certain values through a trigger; only when the trigger condition is met.

I discussed control templates from the perspective of styles and resources. However, control templates have the ability to customize the user interface. Although there are some precautions to take, control templates have the powerful ability to completely redesign the user interface.

In the examples provided, the styles, resources, and control templates are mostly embedded in the main Window. However, it would be a better approach to split them into a more centralized place, like a resource dictionary.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Brian Mains

Brian Mains is an application developer consultant with Computer Aid Inc. He formerly worked with the Department of Public Welfare. In both places of business, he developed both windows and web applications, small and large, using the latest .NET technologies. In addition, he had spent many hou...

This author has published 73 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Integrate Lua into WPF Games
Lua is a world-famous scripting language. It is a lightweight multi-paradigm programming language de...
Creating Video Clips in WPF
In this article we will see how we can clip videos with few kilobytes of memory being used by your h...
Storyboard Playing with Playlist Manager in WPF
In last article we achieved clipping videos out of the parent video. In this article we will see how...
Styles in WPF
In this article, you will learn what are styles, how to create and use styles in WPF applications.
Cascading ListBox Using MVVM in WPF
In this article we will see how we could implement a List Box and using the powerful Model View View...

You might also be interested in the following related blog posts


WPF Wonders: Building Control Templates read more
Telerik Releases New Controls for Silverlight 3 and WPF read more
Q3 2009 Beta released for Telerik RadControls for Silverlight/WPF read more
Custom Panels in Silverlight/WPF Part 4: Virtualization read more
Better XAML By Farr: WPF Line of Business Seminar read more
Resx and BAML Resources in WPF read more
CodeDigest.Com Article,Codes,FAQs - April,2009 read more
Easy way to create a web-based AJAX SFTP Client application read more
WPF Release History : Q1 2009 SP1 (version 2009.1.413) read more
InfoStrat releases a Virtual Earth control for both WPF and Surface to CodePlex read more
Top
 
 
 

Please login to rate or to leave a comment.

Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.