Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Simplify Your XAML with Resources and Control Templates

Although it's tempting to style your WPF controls directly in their containing XAML files or through code, placing styling in control templates stored in external resource dictionaries offers a robust and reusable alternative.


advertisement

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.

    <Grid.Resources>
      <ControlTemplate 
        x:Key="RoundButtonWithThickEdge" 
        TargetType="{x:Type Button}">
        <Grid>
          <Ellipse Fill="{TemplateBinding Background}" 
            Stroke="{x:Null}" 
            HorizontalAlignment="Stretch" x:Name="ellipse"/>
          <ContentPresenter Margin="2" HorizontalAlignment="Center" 
            VerticalAlignment="Center"/>
          <Ellipse Stroke="{x:Null}" Margin="2,3,4,5">
            <Ellipse.Fill>
              <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFFBFAFA" Offset="0"/>
                <GradientStop Color="#1DFFFFFF" Offset="1"/>
              </LinearGradientBrush>
            </Ellipse.Fill>
          </Ellipse>
        </Grid>
      </ControlTemplate>
    </Grid.Resources>
    <Button HorizontalAlignment="Left" Margin="2" 
      Grid.Row="0" Grid.Column="0"
      Width="100" Height="50" 
      Template="{StaticResource RoundButtonWithThickEdge}"
      x:Name="button1" Content="Button 1" 
      Background="Green" Click="Button_Click">
    </Button>
    

    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.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date