Sunday, December 11, 2016

Introduction of Styles


In ley man language wpf style work like HTML CSS, we set properties in style for a control, which make it possible to reuse it in the application. So Style is a way to set some property values to one or more controls.


Take an example to understand this concept.


Suppose we want an application where all TextBlock's background should be Gray, FontStyle Italic and Background Yellow then there are two ways

1. Set the Background and FontStyle property for every TextBlock in application.        <StackPanel Orientation="Horizontal">
            <TextBlock Foreground="Gray" Background="Yellow" FontStyle="Italic" Text="My" Height="25" Margin="5" Padding="5"></TextBlock>
            <TextBlock Foreground="Gray" Background="Yellow" FontStyle="Italic" Text="First" Height="25" Margin="5" Padding="5"></TextBlock>
            <TextBlock Foreground="Gray" Background="Yellow" FontStyle="Italic" Text="Style" Height="25" Margin="5" Padding="5"></TextBlock>
        </StackPanel>
This is not maintainable and scalable so to get rid of this we have a solution says create a style.

       <Window x:Class="WpfTricks.Introduction"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Introduction" Height="150" Width="350">
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray"></Setter>
            <Setter Property="FontStyle" Value="Italic"></Setter>
            <Setter Property="Background" Value="Yellow"></Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="My" Height="25" Margin="5" Padding="5"></TextBlock>
            <TextBlock Text="First" Height="25" Margin="5" Padding="5"></TextBlock>
            <TextBlock Text="Style" Height="25" Margin="5" Padding="5"></TextBlock>
        </StackPanel>
    </Grid>
</Window>


There are some elements to define styles
Setters: Sets the property values
Triggers: Change the style settings
BasedOn: Creates a specialised style that inherits the settings of another style
TargetType: Gets or Sets the Control for which the style is intended   

Setters

Setter is use to set the property of a style 
e.g.
        <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Red"/>
        </Style> 
     
BasedOn

BasedOn is use to inherit the current style and define a new style, the default value of BaseOn is null when we are not using it. it is a very useful way to extend the style. when current style need to unchanged.
example 1:
we have a style in App.xaml for TextBox for foreground red
       <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Red"/>
        </Style>
Text in Textboxes will display with red color, now we need textbox in some windows should have fontsize 14 , then instead of creating complete new style, we can inherit new one and set the fontsize.      
        <Style TargetType="TextBox" x:Key="style2" BasedOn="{StaticResource {x:Type TextBox}}" >
            <Setter Property="FontSize" Value="20"/>
        </Style>
[
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
]
example 2 : When Key is defined
       <Style TargetType="TextBox" x:Key="style1">
            <Setter Property="Foreground" Value="Red"/>
        </Style>

     <Style TargetType="TextBox" x:Key="style2" BasedOn="{StaticResource style1}">
            <Setter Property="FontSize" Value="20"/>
      </Style>
in example 1 we are using x:Key.
if we are using only Target type and not define the key in the style then style will apply to all target Controls( we will understand about key in next paras)x:Key: Define key name to use style in requred element.

How to use x:Key
<TextBlock style="{StaticResource [style key]}"/>
<TextBlock style="{StaticResource style2}"/>

[
<Style x:Key="commonStyle" TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource commonStyle}" />
]


Target Type
In defining style, it need to tell what is its target element, in above code will show error that it is not recognizable property
<Style TargetType="TextBlock">
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="FontFamily" Value="Comic Sans MS"/>
  <Setter Property="FontSize" Value="14"/>
</Style>



TargetType :
Gets or sets the type for which this style is intended(planned).


        <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Red"/>

        </Style>

<Style TargetType="{x:Type [element name]}">
    <!-- Setters -->
</Style>

It insure the type safety.
The style should target a specific type in order to know what properties to set.

Note: However, there is a work around. You can take the common properties of all the types you have and define them in one style. Then make specific styles for each of the specific controls and use the BasedOn property to inherit from the basic style.

Triggers:
Triggers is used in style to perform action on change any property value or event fires. Triggers create visual effects on controls. By using Triggers we can change the appearance of Framework Elements.
i am not explain trigger here, you will read in next post , to read click here.
For every property we need to define one setter in style
We need to write the name of the property and its value.

Understanding Resource Dictionary

Style are define in the resource dictionary.
each style has a unique identifier and target type.
to assign a style in an element a unique key is use with the help of StaticResource markup extension

Advantage: The advantage of creating style is to re-use the style anywhere in its scope, and when ever we need to change in the style , we can change it easily and it will reflect everywhere.
We are now understand how to use style

Scope of style
The Scope of style limits to in which level it is define
Style can be define in following levels.
  • Application Level
  • Window Level
  • Control Level
  • Layout Level
We will read about scope and how to define in different scope in next posts.
Most Basic Example
Example 1:  In the application all text box need with Yellow Background.

In this case we have to create the style for element TextBox, Set property is Background,
    
   <Window x:Class="WpfTricks.BasicStyle"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="TextBox">
            <Setter Property="Background" Value="Yellow"></Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBox Width="200" Height="40"></TextBox>
    </Grid>
  </Window>