Sunday, December 11, 2011

Silverlight: Data Binding

In this article, I am going to explain basic concepts of data binding in Silverlight applications. I will also cover different types of binding modes available in Silverlight. We will cover how to use it declaratively and programmatically.

DATA BINDING
Data binding is the mechanism to display related data available in object (Model) into UI controls(View) and facilitate user to add,change it. Binding includes expressions, data templates, converters, binding modes, and validation.



Binding Expression
It is generally an expression within curly braces '{}' that is used to map property of an object (Model) to UI control (View) inside XAML page.

<StackPanel>
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Path=ID}" />
        <TextBlock Text="{Binding Department.Name}"/>
</StackPanel>
 

The first TextBlock in the above XAML is using a binding expression on its Text property.
The binding expression take the value for this Text property from the Name property of the model.
The second TextBlock is fetching the ID property of the model using a another but equivalent binding expression (the Path word is optional in simple expressions).
It can even navigate an object hierarchy as mentioned in the third TextBlock. In this it will find a Department
property on the model, then fetch the Name property from that object and use that for the Text property.


Data Context
Most Silverlight controls exposes DataContext property. By setting this property controls are notified to use object as model. Thus, the following C# code, combined with the above XAML, will produce the display shown below:
Employee objEmployee = new Employee()
{
    Name = "Durgesh",
    ID = 1,
    Department = new Department() { Name = "Engineering" }
};
this.DataContext = objEmployee;



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.