Styles in WPF


Resources are used to store a wide variety of objects, but one of the most common reasons for using them is to apply a common style to controls. We can compare styles to that of CSS (Cascading Stylesheet used in HTML) or XSLT (Extensible Stylesheet Tranformation) in XML, which are basically used for formatting our HTML or XML data. In the same fashion we can make use of style in WPF to format our control. Once commonly defined, a style will be applied for all the occurrences of the particular control like that of what happens in CSS if you define a style for a table control and you apply the CSS on some of the web page then within that web page every time the table appears the same style is applied. It allows us to apply a set of properties to more than one element at a time.

Once a style has been created we can bind it to a particular control by using a Style property. If you want to create a more specific style you can define the style within that particular control such as that of canvas or stack panel or grid. Style declaration consists of more than one setter object and each setter object has property and values as attribute where we specify the property for which the style we are creating and the value of that property.

Exmaple

<Grid>
        <Grid.Resources>
            <Style x:Key="button" TargetType="Button">
                <Setter Property="Background" Value="Green"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontFamily" Value="Times New Roman"/>
                <Setter Property="FontSize" Value="15"/>
            </Style>
            <Style x:Key="button2" TargetType="Button">
                <Setter Property="Background" Value="Orange"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontFamily" Value="Georgia"/>
                <Setter Property="FontSize" Value="15"/>
            </Style>
        </Grid.Resources>
        <Button Height="23" Style="{StaticResource button}" Margin="30,33,51,0" Name="button1" VerticalAlignment="Top">Button 1</Button>
        <Button Margin="30,121,51,118" Style="{StaticResource button2}"  Name="button2">Button 2</Button>
    </Grid>

NOTE : - the TargetType attribute of the Style where I'm specifying the Button ie the Style which I'm creating is to be applied only for button controls by setting the Style="{StaticResource button}" property of the Button control.

However if you want the style to be applied across the application you can specify it in the app.xaml file or if you want that style is used only for a particular window you can specify it in Window.Resources Tag. You can also make use of Trigger for performing Conditional Formatting. It can be linked to the style by using Style.Trigger Collection. Every style can have an infinite number of triggers and every trigger class inherits from the System.Window.TriggerBase namespace. There are many types of triggers but in this example we'll only be looking at the property trigger. In simple terms we can say that triggers help us to perform conditional formatting like that of XSLT in XML. Here in this example we are considering the TextBox control whose background color changes as the mouse moves over it.

The following is the code snippet:

<Window.Resources>
        <Style x:Key="TextBoxItem" TargetType="TextBox">
            <Setter Property="Background" Value="lightYellow"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Background" Value="lightPink"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBox Style="{StaticResource TextBoxItem}" Height="23" Margin="55,89,103,0" Name="textBox1" VerticalAlignment="Top" />
        <Label Height="28" Margin="30,36,128,0" Name="label1" VerticalAlignment="Top">Place Cursor on TextBox</Label>
    </Grid>


We can also extend from the existing style. This concept we can correlate to that of the child master page where we try to inherit the layout of the master page and then try to override it within the child master page.

We can override an existing style by using the BasedOn attribute of the style class. The following example illustrates this.

<Window.Resources>
        <Style x:Key="ControlOriginal">
            <Setter Property="Control.FontFamily" Value="Georgia"/>
            <Setter Property="Control.FontSize" Value="20"/>
            <Setter Property="Control.FontWeight" Value="Bold"/>
        </Style>
        <Style x:Key="ControlOverride" BasedOn="{StaticResource ControlOriginal}">
            <Setter Property="Control.Background" Value="PaleGreen"/>
            <Setter Property="Control.Foreground" Value="White"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Label Height="28" Style="{StaticResource ControlOriginal}" Margin="52,56,106,0" Name="label1" VerticalAlignment="Top">Label 1</Label>
        <Label Margin="52,103,106,131" Style="{StaticResource ControlOverride}" Name="label2">Label 2</Label>
    </Grid>

The above style can be applied to any type of control which inherit from the control class because within the style we are not specifying the TargetType attribute of the style class and in the property setting of the setter we are specifying Control.FontFamily and many other properties.

I hope you liked the example and it may help you.