devxlogo

Simplify Your XAML with Resources and Control Templates

Simplify Your XAML with Resources and Control Templates

he visual appearance of controls in XAML?their styling?is, unlike Windows Forms controls, completely customizable. XAML offers speedy and uncomplicated ways to style controls, primarily:

  1. Declaratively, through XAML markup
  2. Programmatically, through code

Each approach has its pros and cons. The declarative method has these advantages:

  • It supports rapid coding and prototyping.
  • UI design is isolated from code.
  • Developers can rapidly alter styles.

Despite these advantages, the declarative method also has several disadvantages that take a huge toll in reducing the overall application reusability, because:

  • Developers can’t reuse other developers’ styling easily, because the controls, layout, and styling are intermixed.
  • End users can’t change styles dynamically, because the XAML gets compiled into the application.
  • Excessive style markup makes control definitions difficult to locate and work with.

This article discusses both declarative and programmatic style-setting methods and provides examples. I’ll leave it to readers to decide which approach is the most practical.

Author’s Note: This article is not intended to focus on creating style attributes, but rather to show various ways you can apply them. See the links at the end of this article for more information on style creation.

Applying Styles in Design View

?
Figure 1. Simple Window: This simple window contains four buttons in a Grid control.

First, here’s an example of creating and applying styles through the design view. Start by creating a new WPF application. By default, Visual Studio creates a Window1.xaml file. Set the window properties as follows:

  • Change the Title property to “Styling Buttons.” Change both the Height and Width properties to 250.
  • Add a grid control with two rows and two columns. Place a button control in each cell of the grid, and choose a background color for each button.

In design view, your XAML should look similar to Listing 1.

Save and run the application. You should see a window similar to Figure 1.

Close the program to begin adding control styling through the designer. You can set a control’s style through its Template property. A style can be applied to a control using either a StaticResource or a DynamicResource.

  • Static resources refer to resources available in the Resources collection of an object, and must be present at compile time. Use a StaticResource when the resource you are attaching to is defined in the XAML before it ever gets used, and when it isn’t going to change further. StaticResources provide better performance; they’re resolved at compile time, so any future changes to the actual dictionary object are ignored.
  • Dynamic resources refer to resources that are not available in an object’s Resources collection, and must be present at run time. You can think of a dynamic resource as a deferred lookup for the value. Typically, dynamic resources are implemented as XAML files containing resource dictionaries. For example, the code in Figure 2 shows two styles stored in a single resource dictionary.
  • ?
    Figure 2. Resource Dictionary: This dictionary defines a static resource named ControlBackground.

    Because each control’s container has its own resource collection, you can store the styling XAML in that collection. Each style template has a Key and a TargetType.

                                                                                                

The preceding XAML defines a control template containing the styling in the Grid’s resource collection. The last part of the code sets button1‘s Template property to reference that style template, named RoundButtonWithThickEdge.

When you run the application, you’ll see that the first button displays using the RoundButtonWithThickEdge style (see Figure 3), which defines an ellipse and a gradient background.

?
Figure 3. Styled Button: The elliptical button displays using the RoundButtonWithThickEdge template style defined in its containing grid.

This one-file-defines-all approach is fine for small examples, but as applications grow, as stated earlier, the XAML becomes heavier and cumbersome to read through. Fortunately, you can place style templates in separate files and then load them dynamically (Dynamic Resources) as you’ll see in the next section.

Creating Resource Dictionary Files

You can create resource dictionaries and add as many control style templates to them as you need. Then you can either cause controls to load their template styles dynamically or define specific styles in the design view itself. The examples below illustrate both cases.

?
Figure 4. Adding a Resource Dictionary: From the project’s context menu, choose Add Resource Dictionary to create a new resource dictionary file.

Right-click on your existing project, and choose Add Resource Dictionary from the context menu (see Figure 4).

Name the new resource dictionary file ButtonStyles.Xaml, and add the control template styles shown in Listing 2. This resource file will contain four control templates, each of which has its TargetType set to Button.

Note that each control template has a unique key (x:Key) named according to the resulting button style. Choosing good names helps with control template reuse.

At their simplest, control templates let you manage the visual display of a control using styles, triggers?and much more. It’s also worth noting that every control has a base rendering template built into the system.

With the new control templates safely stored in an external file, to apply them you now need to load them into the Window containing the buttons. Each resource dictionary that you create to hold style templates?in this example?the button content templates, has to be loaded into the parent container’s Resources collection.

In this case, you have two options: You can either load the resources into the Grid’s (RootGrid) resource dictionary, which will make the styles available only to the controls inside the Grid control, or you can load them into the Window’s (Design.Window1) resource dictionary and make them available to all the Window’s child objects. As this example requires the styles only for the buttons in the Grid, the first option seems reasonable.

So, create an event handler for the Window’s Loaded event, and add the following code to it:

/// /// Handles the Loaded event of the Window control./// /// The source of the event./// The    ///    instance containing the event data.private void Window_Loaded(object sender, RoutedEventArgs e){   //Button Styles   ResourceDictionary buttonStyles = new ResourceDictionary();   buttonStyles.Source = (new Uri(      "/Design;component/Styles/Button/ButtonStyles.xaml",       UriKind.RelativeOrAbsolute));   RootGrid.Resources.MergedDictionaries.Add(buttonStyles);}

The preceding code loads the resources into the RootGrid.Resources collection. In the XAML, you can refer to the style as a dynamic resource using the appropriate key:

Running the application now results in the same screen shown earlier in Figure 3, but this time the application is using styles defined in the external resource dictionary.

Applying Styles in Code

What you’ve seen so far is only part of the story, because while the styles are now loaded into the RootGrid’s resources using code, the style is still applied in the XAML. You can set styles through code as well by using the FrameworkElement’s SetResourceReference method and applying the resource to the control’s dependency property. Assigning the styles through code is often a useful alternative to setting up properties in XAML.

Basically, this statement in XAML?

?is equivalent to the code:

button1.SetResourceReference(   Control.TemplateProperty, "RoundButtonWithThickEdge");
?
Figure 5. Programmatically Applied Styles: This version of the application programmatically applied styles stored in the dictionary file ButtonStyles.Xaml.

As an example, the following code applies styling to two of the remaining buttons:

//Set the template property in code // by using the Property and a Key.button1.SetResourceReference(Control.TemplateProperty,    "RoundButtonWithThickEdge");button2.SetResourceReference(Control.TemplateProperty,    "RoundGelButton");button3.SetResourceReference(Control.TemplateProperty,    "Flattish"); 

Remove the previously set TemplateProperty for button1 applied in the XAML, and add the preceding code to style the remaining buttons. With that code in place, run the application again (see Figure 5). Note the round gel gradient style of Button 2 and the flattish style of Button 3.

As you can see, it’s far more fun playing with XAML styles than applying oneself to serious learning, but for those who want to explore some more, here are some good links for learning how to use Expression Blend:

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist