Saturday, August 20, 2011

Styles in WPF


What is Style?

A style is a collection of property values that can be applied to an element. Most of the time you need to set most common properties like margin, horizontal alignment, vertical alignment, padding, color, fonts etc. on many elements of your application. A style can be useful at that time. WPF style is similar to CSS (Cascading Style Sheets) in HTML. A style can set any Dependency Property. Let’s have a look on below XAML code. 

<StackPanel>
    <Button Name="Cut" Content="Cut" Width="125"
            Height="40" HorizontalAlignment="Center"
            FontFamily="Arial" FontSize="16"
            Background="LightBlue"
            VerticalAlignment="Top" Margin="5" />
    <Button Name="Copy" Content="Copy" Width="125"
            Height="40" HorizontalAlignment="Center"
            FontFamily="Arial" FontSize="16"
            Background="LightBlue"
            VerticalAlignment="Top" Margin="5" />
    <Button Name="Paste" Content="Paste" Width="125"
            Height="40" HorizontalAlignment="Center"
            FontFamily="Arial" FontSize="16"
            Background="LightBlue"
            VerticalAlignment="Top" Margin="5" />
</StackPanel>














In above code, same properties are set multiple times which is not good practice. Sometimes we need to set some properties for some specific group of elements. So let’s have a look on below code to understand how Style is useful in this scenario.

<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="Width" Value="125" />
        <Setter Property="Height" Value="40" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="FontFamily" Value="Arial" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Background" Value="LightBlue" />
        <Setter Property="Margin" Value="5" />
    </Style>
</Window.Resources>
<StackPanel>
    <Button Name="Cut" Content="Cut" />
    <Button Name="Copy" Content="Copy" />
    <Button Name="Paste" Content="Paste" />
</StackPanel>














The above code gives same output as first example gave. Style is used to set multiple properties for Button type. So every Button will automatically set all the properties defined in Style. Style is defined in Window.Resources this also can be set on each element also.  Style is collection of setters and each setter defines property name and value so this setter collection will automatically applies to target type defined with Style.

Named Styles

Sometimes you want to apply style to some of the elements not to all. In this case you can specify key on style and set to specific element which you want to apply style. Let’s have a look on below code.


<Window.Resources>
    <Style x:Key="MyButtonStyle" TargetType="Button" >
        <Setter Property="Width" Value="125" />
        <Setter Property="Height" Value="40" />
  ….
    </Style>
</Window.Resources>
<StackPanel>
    <Button Name="Cut" Content="Cut"
            Style="{StaticResource MyButtonStyle}" />
    <Button Name="Copy" Content="Copy" />
    <Button Name="Paste" Content="Paste"
            Style="{StaticResource MyButtonStyle}" />
</StackPanel>












You can see in above image style is applied specifically to Cut and Paste button only and copy button remains unchanged. If we set name for style (x:Key) then the style won’t apply to all target element specified on style instead it will apply to only element where you specifically set Style property.   

How to inherit Style?

Basedon property of style allows inheriting styles of base style. Sometimes we need to set some common properties to all elements but want to specify few special properties to few elements. In WPF you can set only one style to element multiple styles can’t be set for an element. So you need this basedon feature in this case.

<Window.Resources>
    <Style x:Key="MyButtonStyle" TargetType="Button" >
        <Setter Property="Width" Value="125" />
        <Setter Property="Height" Value="40" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="FontFamily" Value="Arial" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Background" Value="LightBlue" />
        <Setter Property="Margin" Value="5" />
    </Style>
    <Style x:Key="CopyButtonStyle" TargetType="Button"
           BasedOn="{StaticResource MyButtonStyle}">
        <Setter Property="Background" Value="LightGreen" />
    </Style>
    <Style x:Key="CutButtonStyle" TargetType="Button"
           BasedOn="{StaticResource MyButtonStyle}">
        <Setter Property="Background" Value="LightCoral" />
    </Style>
</Window.Resources>
<StackPanel>
    <Button Name="Cut" Content="Cut"
            Style="{StaticResource CutButtonStyle}" />
    <Button Name="Copy" Content="Copy"
            Style="{StaticResource CopyButtonStyle}" />
    <Button Name="Paste" Content="Paste"
            Style="{StaticResource MyButtonStyle}" />
</StackPanel>














In above code, CopyButtonStyle and CutButtonStyle are basedon MyButtonStyle. So it will have all the properties defined in MyButtonStyle and also it can override or add few properties. In this example i override background property and set some different background color for Cut and Copy button.

EventSetters in Style

Event can also be attached inside style. Style provides EventSetter inside you can add EventName and attach appropriate handler for that event.

<Window.Resources>
<Style x:Key="MyButtonEvent" TargetType="Button">
    <EventSetter Event="MouseEnter" Handler="Button_MouseEnter" />
    <EventSetter Event="MouseLeave" Handler="Button_MouseLeave" />
</Style>
</Window.Resources>
<StackPanel>
    <Button Name="Cut" Content="Cut"
            Height="40" Width="150"
        Style="{StaticResource MyButtonEvent}" />
</StackPanel>

private void Button_MouseEnter(object sender, MouseEventArgs e)
{
    Button btn = sender as Button;
    btn.Background = Brushes.Red;
}
private void Button_MouseLeave(object sender, MouseEventArgs e)
{
    Button btn = sender as Button;
    btn.Background = Brushes.Green;
}










In above example you can see that Button_MouseEnter and Button_MouseLeave handler is attached inside EventSetter of Style. Whenever mouse enter and leave it will change button background color.


See also


No comments:

Post a Comment