Styles in WPF - CodeProject

:

Styles in WPF have been introduced to have a consistent look and feel of UI. E.g. all the buttons in our application should have same color, height , width and other properties. 

 

Style are objects which contains setters  objects (and trigger which I will dicuss in another article)collection which in turn can be used to assign the properties of a control. Each setter can be used to set the property which needs to be a dependency property .What a CSS in HTML does to control is same as what Style does to control in WPF.
We need to take care of following things while using styles –

1.        Setting a style or property locally will override the style defined above in the element tree.
2.        Styles can be set in the following two ways which I will discuss later

3.        Styles are decalred as resources  so that they can be used by the elements below them in element tree.

Named Style  

We can always declare a key for the style which can been used in the application down the element tree by specifying the key for the style.  An example of the named style in the resource is shown below.

                            

 <Window.Resources>  
    <Style x:Key="buttonNamedStyle">  
        <Setter Property="Button.Height" Value="40"></Setter>  
        <Setter Property="Button.Width" Value="100"></Setter> 
        <Setter Property="Button.Background" Value="Red"></Setter>  
    </Style>     
</Window.Resources>  

 

I have defined a style for the button in the window resource. As we can see in the snippet I have provided a name for the style using x:key element. Futher I have defined values for number of styles using the Setter attribute. However we need to keep one point in mind while using named style is that while defining setter we need to provide the element name along with the propertyName in the property e.g. Button.Height as shown in the above code snippet. It doesn’t need to be the exact class name, it can also be the classs name from which the control derives e.g.  Control.Height which  in turn would help you to apply the property for any class down the Hierarchy ferived from that control. If some of the properties are relevant for the target control they would be simply ignored.  Now I will show how it can be used.

                      
  1. <Grid>  
         <Grid.ColumnDefinitions>  
              <ColumnDefinition></ColumnDefinition> 
            <ColumnDefinition></ColumnDefinition> 
         </Grid.ColumnDefinitions>   
         <Button Style="{StaticResource ResourceKey=buttonNamedStyle}" Content="MyButton" Grid.Column="0"></Button>  
         <Button Content="MyButton" Grid.Column="1"></Button>  
     </Grid>  

In the above code snippet I have used two button. One button explicitly uses the style definesd in resources section of the window and other one is not at all using any style. When we run the application we can see the difference between the two buttons as shown in the figure below.

Picture

 

Targeted Styles

This style is designed to provide a style for some particular type of control only and is applied automatically to the elements of the type below the element tree in the declaration. Below is the code snippet for the targeted style.

                               
  1. <Style TargetType="Button">  
        <Setter Property="Height" Value="40"></Setter> 
        <Setter Property="Width" Value="100"></Setter> 
        <Setter Property="Background" Value="Red"></Setter>    
    </Style> 
The changes which we can notice from that of the names style are as following.
1.  There is no x:Key.
2.  We have used TargetType attribute.
3.  In the setter we have removed the class name from Property attribute.

As soon as we apply this style in the resources section of the window both of the buttons which we have used in the previous section are changed as shown in the below figure, which shows that whatever elements come down in the element tree they take the style by default.

Picture

 

One more change I want to bring to your notice is that, if we are using targeted style in that case there is no need to use the Style attribute for the button as have used for the first button in Named Style.

Style Inheritance   

Styles in WPF also supports inheritane much like the inheritance in the OOP. This can be done using the BasedOn property that must point to other style to inherit from. If there is a target type specified in the base style it must be specified in the derived style also. Please check the below code snippet to get more about the BasedOn Property.

                        
  1. <Window.Resources>  
            <Style TargetType="Button" x:Key="mybaseStyle">  
                <Setter Property="Height" Value="40"></Setter> 
                <Setter Property="Width" Value="100"></Setter> 
                <Setter Property="Background" Value="Red"></Setter>   
            </Style>   
            <Style TargetType="Button" x:Key="derivedStyle" BasedOn="{StaticResource ResourceKey=mybaseStyle}">  
                <Setter Property="FontWeight" Value="ExtraBold" />  
                <Setter Property="Effect">  
                    <Setter.Value>  
                        <DropShadowEffect Color="Black" />  
                    </Setter.Value>  
                </Setter>  
            </Style>  
        </Window.Resources> 
And the output as shown in the figure below.
Picture

 

However it is not recommended to have more than one level of inheritance as it would be a nightmare to debug the changes if we have multiple levels.

Automatic Style

We can define a particular style for whole of the application for a single control by defining it in the App.xaml as shown below . These styles are created without key.                    

 

 <Application.Resources>    
   <Style TargetType="Button">  
     <Setter Property="Height" Value="40"></Setter>  
     <Setter Property="Width" Value="100"></Setter> 
     <Setter Property="Background" Value="Red"></Setter>  
   </Style>          
</Application.Resources>   

 

If we want to revert the default style for the control we need to set the style as null (x:Null in xaml) or set the style to another named style. We can also create a style based on the application style as shown below.      

                      

<Style TargetType="Button" x:Key="myButtonStyle"  BasedOn="{StaticResource {x:Type Button}}">   


The myButtonStyle in the example above derives from the automatic style and this is specified by looking up a resource with the key of typeof(Button) , expressed in XAML as {x:Type Button} .