Sunday, October 16, 2011

Silverlight: Different ways to apply Styles

The concept of applying Style in Silverlight is similar to using CSS in HTML.
In this article I am going to explain what are different ways to implement Styles for Silvelight Controls.

Styles provides flexibility & ability to control the visual representation of all UI controls. Each silverlight control can be represented using XAML elements. These XAML elements has a series of attributes that set to make style for control.
Style can be created as:
  1. Inline Styles
  2. Styles as Resource
  3. Inheriting Styles
Style must contain following elements & attributes:
  1. TargetType attribute The TargetType attribute is a string that specifies a FrameworkElement the style should be applied to. The TargetType value must specify a FrameworkElement-derived type in the Silverlight runtime or a referenced assembly. If you attempt to apply a style to a control that does not match the TargetType attribute, an exception will occur.
  2. A Setters collection with one or more Setter elements
    Each Setter element requires a Property and a Value. These property settings indicate what control property the setting applies to, and the value to set for that property. Setter.Value can be set with attribute or element syntax. 
  3. x:Key attribute (optional)
For example:
<Style TargetType="TextBlock" x:Key="TextBlockStyle">
      <Setter Property="Foreground" Value="Navy"/>
      <Setter Property="FontSize" Value="14"/>
      <Setter Property="VerticalAlignment" Value="Bottom"/>
</Style> 
 
There are two ways to apply styles to controls:
  1. Implicitly, by only specifying a TargetType for the Style.
  2. Explicitly, by specifying a TargetType and an x:Key attribute for the Style and then by setting the target control's Style property to this key.

If a style contains the x:Key attribute, it can be applied to a control by setting the Style property of the control to the keyed style and if without an x:Key attribute, it is automatically applied to every control of its target type, if the control does not have an explicit style setting.
Implicit Style:
<Style TargetType="Button">
            <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform Angle="25"/>
                </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush" Value="OrangeRed"/>
            <Setter Property="BorderThickness" Value="2"/>
            <Setter Property="Foreground" Value="OrangeRed"/>
</Style>

Explicit Style

<Style x:Key="PurpleButton" TargetType="Button">

            <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>

            <Setter Property="FontStyle" Value="Italic"/>

            <Setter Property="FontSize" Value="14"/>

            <Setter Property="RenderTransform">

                <Setter.Value>

                    <RotateTransform Angle="25"/>

                </Setter.Value>

            </Setter>

            <Setter Property="BorderBrush" Value="OrangeRed"/>

            <Setter Property="BorderThickness" Value="2"/>

            <Setter Property="Foreground" Value="OrangeRed"/>

</Style> 

  1.  Inline styles:      
    <Button Content="Button" Height="23" HorizontalAlignment="Left"
                    Margin="100,10,0,0" Name="button2" VerticalAlignment="Top" Width="75" FontFamily="Lucida Sans Unicode" FontStyle="Italic" FontSize="14"/>

    Another way to define Inline style:

    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" >
                <Button.Style>
                    <Style TargetType="Button">
                        <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>

                        <Setter Property="FontStyle" Value="Italic"/>
                        <Setter Property="FontSize" Value="14"/>
                        <Setter Property="RenderTransform">

                            <Setter.Value>

                                <RotateTransform Angle="25"/>

                            </Setter.Value>

                        </Setter>

                        <Setter Property="BorderBrush" Value="OrangeRed"/>

                        <Setter Property="BorderThickness" Value="2"/>

                        <Setter Property="Foreground" Value="OrangeRed"/>

                    </Style>
                </Button.Style>
            </Button>
  2. Style as Resource
    Creating style as resource provides the flexibilty to apply it to many of same type of controls. There are different scope level resource that can declared inside application. It can be declared as:
    1. UserControl level:  used to only the element on that UserControl. 
    2. Application Level:  used and applied to element to whole application.
    3. Resource Dictionary: used and applied to element to whole application.
  1. UserControl Level Resource
    Resources that are for use only within a single Silverlight UserControl are defined in the XAML of the UserControl.  All resources defined at this level are defined between the Resources opening and closing tags which are declared directly under where the UserControl is defined and before any elements.
    <UserControl x:Class="SilverlightApplication4.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:dg="http://durgeshg.blogspot.com"            
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
       
        <UserControl.Resources>
            <Style TargetType="Button">
                <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>
                <Setter Property="FontStyle" Value="Italic"/>
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="RenderTransform">
                    <Setter.Value>
                        <RotateTransform Angle="25"/>
                    </Setter.Value>
                </Setter>
                <Setter Property="BorderBrush" Value="OrangeRed"/>
                <Setter Property="BorderThickness" Value="2"/>
                <Setter Property="Foreground" Value="OrangeRed"/>
            </Style>
        </UserControl.Resources>
        <Grid x:Name="LayoutRoot" Background="White">
            <Button Content="Button" Height="23" HorizontalAlignment="Left"
                    Margin="100,10,0,0" Name="button2" VerticalAlignment="Top" Width="75" />                  
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" >       
            </Button>

            <Rectangle Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="200" />       
        </Grid>
    </UserControl>
     
  2. Application Level ResourcesIf the style is required & to be applied across application then the style definition can be placed in the resources collection inside the App.xaml file.
    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 x:Class="SilverlightApplication4.App"
                 >
        <Application.Resources>
            <Style x:Key="TranformedPurpleButton" TargetType="Button">
                <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>
                <Setter Property="FontStyle" Value="Italic"/>
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="RenderTransform">
                    <Setter.Value>
                        <RotateTransform Angle="25"/>
                    </Setter.Value>
                </Setter>
                <Setter Property="BorderBrush" Value="OrangeRed"/>
                <Setter Property="BorderThickness" Value="2"/>
                <Setter Property="Foreground" Value="OrangeRed"/>
            </Style>
        </Application.Resources>
    </Application>

    Apply this style to controls as following

    <UserControl x:Class="SilverlightApplication4.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:dg="http://durgeshg.blogspot.com"            
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
           
        <Grid x:Name="LayoutRoot" Background="White">
            <Button Content="Button" Height="23" HorizontalAlignment="Left"
                    Margin="100,10,0,0" Name="button2" VerticalAlignment="Top" Width="75" Style="{StaticResource TranformedPurpleButton}" />                  
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" >       
            </Button>

            <Rectangle Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="200" />       
        </Grid>
    </UserControl>

    How to use from Code Behind:
    button1.Style = Application.Current.Resources["TranformedPurpleButton"] as Style;
  3. Resource Dictionary
    In order to place style into resource dictionary, right click on the Silverlight project and Add
    New Item Select Silverlight Resource Dictionary. Name is a Styles.xaml


    Add Styles as following:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

        <Style x:Key="TranformedPurpleButton" TargetType="Button">
            <Setter Property="FontFamily" Value="Lucida Sans Unicode"/>
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform Angle="25"/>
                </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush" Value="OrangeRed"/>
            <Setter Property="BorderThickness" Value="2"/>
            <Setter Property="Foreground" Value="OrangeRed"/>
        </Style>
       
    </ResourceDictionary>


    Now add this resource dictionary in the app.xaml as following:

    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 x:Class="SilverlightApplication4.App"
                 >
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Styles.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>

     How to use from Code Behind:
    button1.Style = Application.Current.Resources["TranformedPurpleButton"] as Style;
  1.  Inheriting Styles
    To make styles easier to maintain and to optimize style reuse, style can be created that inherit from other styles. You use the BasedOn property to create inherited styles. Styles that inherit from other styles must target the same type of control or a control that derives from the type targeted by the base style. For example, if a base style targets ContentControl, styles that are based on this style can target ContentControl or types that derive from ContentControl such as Button and Label. If necessary, based-on styles can override values in the base style. The following example shows a Button and a CheckBox with styles that inherit from the same base style.

    <UserControl x:Class="SilverlightApplication4.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:dg="http://durgeshg.blogspot.com"            
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
       

        <UserControl.Resources>
            <Style x:Key="BasicStyle" TargetType="ContentControl">
                <Setter Property="Width" Value="100" />
                <Setter Property="Height" Value="30" />
                <Setter Property="Effect" >
                    <Setter.Value>
                        <DropShadowEffect Color="Black" Direction="320" ShadowDepth="15"
                            BlurRadius="5" Opacity="0.2" />
                    </Setter.Value>
                </Setter>
            </Style>
            <Style TargetType="Button" BasedOn="{StaticResource BasicStyle}">
                <Setter Property="BorderBrush" Value="OrangeRed" />
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="Foreground" Value="OrangeRed" />
            </Style>
            <Style TargetType="CheckBox" BasedOn="{StaticResource BasicStyle}">
                <Setter Property="BorderBrush" Value="Green" />
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="Foreground" Value="Green" />
            </Style>
        </UserControl.Resources>

        <Grid x:Name="LayoutRoot" Background="White">
            <Button Content="Button" Height="23" HorizontalAlignment="Left"
                    Margin="100,10,0,0" Name="button2" VerticalAlignment="Top" Width="75" Style="{StaticResource TranformedPurpleButton}" />                  
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" >       
            </Button>

            <Rectangle Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="200" />       
        </Grid>
    </UserControl>

    That's it folks. I hope you like it.
    Comments, feedback & questions are always welcome.

No comments:

Post a Comment