ARTICLE

Style Controls in XAML

Posted by Mahesh Chand Articles | XAML December 18, 2012
XAML is the universal language for WPF, Silverlight, and Windows Store app user interfaces. In this article, we will learn how to create and use styles on UI elements using XAML.
Reader Level:

XAML is the universal language for Windows Presentation Foundation (WPF), Silverlight, and Windows Store app user interfaces such as Windows, Pages and controls. In this article, we will learn how to create and use styles on UI elements using XAML. Once you know how this is done in XAML, you can use the same approach in your WPF, Silverlight, and Windows Store apps. 

This sample is created using a WPF application using Visual Studio 2012. 

Styling is a way to group similar properties in a single Style element and apply on multiple XAML elements. 

Let's have a look at the XAML code in Listing 1 that generates Figure 1. This code creates a Window with three Button controls, a TextBlock, and a TextBox.

 <Window x:Class="StylesSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="291" Width="455">
    
      
    <Grid Height="236" Width="405">
        
        <TextBlock Margin="12,52,26,83" Name="textBlock1" 
                   Background="Gray" Foreground="Orange"
                   FontFamily="Georgia" FontSize="12"
                   Width="370" Height="100" />
        <TextBox Height="30" Margin="11,16,155,0" Name="textBox1" VerticalAlignment="Top" />
        
        <Button HorizontalAlignment="Right" Margin="0,14,26,0"
                Name="button1" VerticalAlignment="Top" 
                Height="30" Width="120"
                FontFamily="Verdana" FontSize="14" FontWeight="Normal"
                Foreground="White" Background="DarkGreen" 
                BorderBrush="Black" >
            Browse
        </Button>        
        <Button HorizontalAlignment="Right" Margin="0,0,30,39" Name="button2" 
                VerticalAlignment="Bottom" 
                Height="30" Width="120"
                FontFamily="Verdana" FontSize="14" FontWeight="Normal"
                Foreground="White" Background="DarkGreen" 
                BorderBrush="Black" >
            Spell Check
        </Button>
        <Button Margin="129,0,156,39" Name="button3" VerticalAlignment="Bottom"
                Height="30" FontFamily="Verdana" FontSize="14" FontWeight="Normal"
                Foreground="White" Background="DarkGreen" 
                BorderBrush="Black" >
            Save File
        </Button>
    </Grid>
</Window>

Listing 1

The output of Listing 1 XAML creates a window that looks like Figure 1. As you can see from Figure 1, all three buttons have the same width, height, background, foreground, and fonts. 
 
Styles-in-WPF.png
Figure 1

Here is the Button element code that sets Height, Width, Foreground, Background, and Font properties.

 <Button HorizontalAlignment="Right" Margin="0,14,26,0"
                Name="button1" VerticalAlignment="Top" 
                Height="30" Width="120"
                FontFamily="Verdana" FontSize="14" FontWeight="Normal"
                Foreground="White" Background="DarkGreen" 
                BorderBrush="Black" >
            Browse
        </Button>   


All of the three buttons have the same values. 

Now, imagine you have a large application with many windows and pages and they have many buttons with the same size and look. That means you will have to repeat the same XAML in every window that you need a Button. 

Let's say, your application is finished and now your client wants to change a green background color to a red background color. You will have to go to each page and find and change the background color from green to red.

But there is a better way to do that. You can create a resource style and use that for every Button control. The next time that you need to change a property, all you need to do is change the value in the resource. 

The Style element in XAML represents a style. A Style element is usually added to the resources of a FrameworkElement. The x:Key is the unique key identifier of the style. The TargetType is the element type such as a Button. 

The code snippet in Listing 2 adds a Style to the Window Resources and within the Style we use a Setter to set the property type and their values. The code snippet sets Width, Height, FontFamily, FontSize, FontWeight, Foreground, Background, and BorderBrush properties. 

 <Window.Resources>
    <!-- Green Button Style -->
    <Style x:Key="GreenButtonStyle" TargetType="Button" >
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="30"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="FontWeight" Value="Normal"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Background" Value="DarkGreen"/>
        <Setter Property="BorderBrush" Value="Black"/>
    </Style>
</Window.Resources>

Listing 2

Note: If you do not specify the TargetType, you can explicitly specify it in the Setter as in the following:

<Setter Property="Button.Width" Value="120"/>

Once a Style is added to the resource dictionary, you can use it by using the Style property of a FrameworkElement. The code snippet in Listing 3 sets the Style of a Button using the StaticResource Markup Extension.

 <Button HorizontalAlignment="Right" Margin="0,14,26,0"
        Name="button1" VerticalAlignment="Top" 
        Style="{StaticResource GreenButtonStyle}"  >
    Browse
</Button>

Listing 3

Now we can replace Listing 1 with much cleaner and manageable code listed in Listing 4. If we need to change the background color of Buttons from green to red, all we have to do is, change the Background property in the resources. 

 <Window x:Class="StylesSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="291" Width="455">
    
    <Window.Resources>
     <Style x:Key="GreenButtonStyle" TargetType="Button" >
            <Setter Property="Width" Value="120"/>
            <Setter Property="Height" Value="30"/>
            <Setter Property="FontFamily" Value="Verdana"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="DarkGreen"/>
            <Setter Property="BorderBrush" Value="Black"/>
        </Style>
    </Window.Resources>
            
    <Grid Height="236" Width="405">
        
        <TextBlock Margin="12,52,26,83" Name="textBlock1" 
                   Background="Gray" Foreground="Orange"
                   FontFamily="Georgia" FontSize="12"
                   Width="370" Height="100" />
        <TextBox Height="30" Margin="11,16,155,0" Name="textBox1" VerticalAlignment="Top" />
        
       <Button HorizontalAlignment="Right" Margin="0,14,26,0"
                Name="button1" VerticalAlignment="Top" 
                Style="{StaticResource GreenButtonStyle}"  >
            Browse
        </Button>
        <Button HorizontalAlignment="Right" Margin="0,0,30,39" Name="button2" 
                VerticalAlignment="Bottom" 
                Style="{StaticResource GreenButtonStyle}" >
            Spell Check
        </Button>
        <Button Margin="129,0,156,39" Name="button3" VerticalAlignment="Bottom"
                Style="{StaticResource GreenButtonStyle}" >
            Save File
        </Button>
        
    </Grid>
</Window>

Style Element

In the previous example, we saw how a Style element can be used within the resources to group multiple properties of elements and set them using the Style property of elements. However, Style functionality does not end here. Style can be used to group and share not only properties but also resources, and event handlers on any FrameworkElement or FrameworkContentElement. 

Styles are resources and used as any other resources and applies to the current element, parent element, root element and even at the application level. The scope if styles are similar to any other resources. The resource lookup process first looks up for local styles and if not found, it traverses to the parent element in the logical tree and so on. In the end, the resource lookup process looks for styles in the application and themes. 

A Style element in XAML represents a style.  The typical definition of a Style element looks as in the following:

<Style>
  Setters
</Style>

As you can see from the definition of Style, a Style has one more Setter element. Each Setter consists of a property and a value. The property is the name of the property and value is the actual value of that property of the element to that the style will be applied to. 

Setters Property

The Setters property of Type represents a collection of Setter and EventSetter objects. Listing 4 uses the Setters property and adds a Setter and EventSetter objects. 

The code snippet in Listing 4 sets the Setters property of a Style by adding a few Setter elements and one EventSetter element using XAML at design-time. 

 <Grid>
    <Grid.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="30"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="DarkGreen"/>
            <Setter Property="BorderBrush" Value="Black"/>
            
            <EventSetter Event="Click" Handler="Button1_Click"/>
        </Style>
    </Grid.Resources>
    
    <Button>Click me</Button>
</Grid>

Listing 4

BasedOn Property

Styles support inheritance. That means we can create styles based on existing styles. When you inherit a style from an existing style, settings from parent style are available in the inherited style. To inherit a style from another style, we set the BasedOn property to StaticResource Markup Extension as the style it is being inherited from. 

The code snippet in Listing 5 creates a Style BackForeColorStyle that sets the Background and Foreground properties of the control. Then we create a FontStyle style that sets font properties but is inherited from the BackForeColorStyle. The last style ButtonAllStyle is inherited from FontStyle. In the end, we set the Style of the button. 

 <Grid Name="RootLayout">
    <Grid.Resources>
        <Style x:Key="BackForeColorStyle">
            <Setter Property="Control.Background" Value="Green"/>
            <Setter Property="Control.Foreground" Value="White"/>
        </Style>

        <Style x:Key="FontStyle" BasedOn="{StaticResource BackForeColorStyle}">
            <Setter Property="Control.FontFamily" Value="Verdana"/>
            <Setter Property="Control.FontSize" Value="14"/>
            <Setter Property="Control.FontWeight" Value="Normal"/>
        </Style>

        <Style x:Key="ButtonAllStyle" BasedOn="{StaticResource FontStyle}">
            <Setter Property="Button.Width" Value="120"/>
            <Setter Property="Button.Height" Value="30"/>
        </Style>
    </Grid.Resources>
          
     <Button Name="Button1" Style="{StaticResource ButtonAllStyle}" >
         Click me
     </Button>  
  </Grid>

Listing 4

TargetType Property

The TargetType property can be used to get and set the type for which a style is intended. If the TargetType property of a Style is set and you assign a style to element that is not the type set in TargetType, you will get an error. 

If the TargetType property is not set, you must set the x:Key property of a Style.

Let's take a quick look at code listed in Listing 5. This code creates a Style named GreenButtonStyle and sets very many Button properties. 

 <Grid>

    <Grid.Resources>
        <!-- Green Button Style -->
        <Style x:Key="GreenButtonStyle" >
            <Setter Property="Button.Width" Value="120"/>
            <Setter Property="Button.Height" Value="30"/>
            <Setter Property="Button.FontFamily" Value="Verdana"/>
            <Setter Property="Button.FontSize" Value="14"/>
            <Setter Property="Button.FontWeight" Value="Normal"/>
            <Setter Property="Button.Foreground" Value="White"/>
            <Setter Property="Button.Background" Value="DarkGreen"/>
            <Setter Property="Button.BorderBrush" Value="Black"/>
        </Style>        
    </Grid.Resources>
    
    <Button HorizontalAlignment="Right" Margin="0,14,26,0"
            Name="button1" VerticalAlignment="Top" 
            Style="{StaticResource GreenButtonStyle}"  >
        Browse
    </Button>
    
</Grid>

Listing 5

Now can simply replace the Style code in Listing 5 with that Listing 6 where you may notice that we have set TargetType = "Button" but have removed Button in front of the properties. By setting TargetType fixes that this style can be applied to a Button element only. 

 <!-- Green Button Style -->
            <Style x:Key="GreenButtonStyle" TargetType="Button" >
                <Setter Property="Width" Value="120"/>
                <Setter Property="Height" Value="30"/>
                <Setter Property="FontFamily" Value="Verdana"/>
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="FontWeight" Value="Normal"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="Background" Value="DarkGreen"/>
                <Setter Property="BorderBrush" Value="Black"/>
            </Style>   
     
Listing 6

Triggers Property

Styles can use triggers within them. The Triggers property of Style represents the triggers applicable on a Style. For example, the following code snippet adds a Trigger for a button when the Button is in a pressed state; it will change the Foreground color of the button to Orange. 

<Style.Triggers>
      <Trigger Property="IsPressed" Value="true">
            <Setter Property = "Foreground" Value="Orange"/>
       </Trigger>
</Style.Triggers>

Listing 6 shows the complete code of implementing triggers within a style.

 <Grid>

    <Grid.Resources>
        <!-- Green Button Style -->
        <Style x:Key="GreenButtonStyle" TargetType="Button" >
            <Setter Property="Width" Value="120"/>
            <Setter Property="Height" Value="30"/>
            <Setter Property="FontFamily" Value="Verdana"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="DarkGreen"/>
            <Setter Property="BorderBrush" Value="Black"/>

            <Style.Triggers>
                <Trigger Property="IsPressed" Value="true">
                    <Setter Property = "Foreground" Value="Orange"/>
                 </Trigger>
            </Style.Triggers>

        </Style>
    </Grid.Resources>

    <Button HorizontalAlignment="Right" Margin="0,14,26,0"
            Name="button1" VerticalAlignment="Top" 
            Style="{StaticResource GreenButtonStyle}"  >
        Browse
    </Button>
</Grid>

Listing 6


Summary

XAML has become quite popular in recent days after the popularity of WPF, Silverlight, Windows Phone and Windows Store apps. In this article, we saw how to use XAML to apply style on XAML elements. 


COMMENT USING

Trending up