Styles and Templates in Silverlight

Styles

This post has very short code snippets to explain the styles and templates in Silverlight.

Styles are used to set the properties of a UI control. For example this shows the inline style setting of a Button control.

<Button Content="Direct Styling" Height="30" Margin="12,73,298,197" Width="90"> <Button.Style> <Style TargetType="Button"> <Setter Property="Background" Value="DarkOrange"/> <Setter Property="BorderBrush" Value="Blue"/> </Style> </Button.Style> </Button>

This is not interesting, because you can do this without using a Style tag by directly setting the Background and BorderBrush properties of a Button.

It is very useful when you declare the style definition as a resource. Then you name the style and can use across different Button controls as shown below.

Here you can notice for the Background property I have used the attached properties. It is possible since Value is an attached property of Style.

<UserControl.Resources> <Style TargetType="Button" x:Name="colorfulButtonStyle2"> <Setter Property="BorderBrush" Value="Red"></Setter> <Setter Property="BorderThickness" Value="5"></Setter> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="DarkRed"></GradientStop> <GradientStop Color="Chocolate" Offset="1"></GradientStop> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </UserControl.Resources>

Usage

<Button Style="{StaticResource colorfulButtonStyle2}" Content="I'm Colorful" Width="90" Margin="12,12,298,257" Click="Button_Click" Height="30" />

In the above Style declaration I have named the style as ‘colorfulButtonStyle2’. If you do not use a name then all the Buttons in the page will use the style automatically without the need of explicitly setting the Style. (In some applications it is useful mainly if you want all your buttons look same)

Styles also support inheritance. Though it is not recommended you can inherit a Style who’s TargetType is different from the one who inherits.

If you have a style defined for TextBox where it sets the BorderBrush, you can inherit this from a different style who’s TargetType is Button. This is possible because both the TextBox and the Button have the BorderBrush property.

Inheritance will raise errors only if the controls do not have the matching properties. But as a matter of a convention / good practice inheritance of Styles between two different types is not recommended.

Inheritance is done via BasedOn tag.

<Style TargetType="Button" x:Name="anotherStyle" BasedOn="{StaticResource colorfulButtonStyle2}"> <Setter Property="Background" Value="Green"></Setter> </Style>

Here the child will override the styles of the parent.

Templates

Templates allow you to change the visual “face” of any common control. In other words, if
you can’t get the custom appearance you want by tweaking properties alone (and often you
can’t), you can almost certainly get it by applying a new template.

And although creating custom templates is more work than just setting control properties, it’s still far simpler and more flexible than developing an entirely new custom control, which many other programming frameworks force you to do

In Silverlight every control has a way to be rendered. Controls are consist of other basic controls. Example Button is a complex control which consists of Rectangale, Border and other basic controls. This is known as Control Template.

<ControlTemplate x:Key="RawButtonTemplate" TargetType="Button"> <Border BorderBrush="BlueViolet" BorderThickness="3" CornerRadius="4" Background="Red"> <TextBlock Text="Custom Button Template"></TextBlock> </Border> </ControlTemplate>

Above we have defined the Control Template for the Button. You can see in Template we have the flexibility to go beyond the control’s properties and customize them.

<Style x:Key="ButtonStyle" TargetType="Button"> <Setter Property="Background" Value="Green"/> </Style>

 

We have a defined a style as well. Let’s see what happens when we apply these two to a Button. Because both the template and the style set the Background property.

<Button Content="Button" Height="46" HorizontalAlignment="Left" Margin="20,26,0,0" Name="button1" VerticalAlignment="Top" Width="166" Style="{StaticResource ButtonStyle}" Template="{StaticResource RawButtonTemplate}" Click="button1_Click" />

Output image

 

 

Few things to notice here, first it is obvious Style is rejected. Next we have set the Content property of the Button as ‘Button’. And it is overridden by the Control Template’s TextBlock control. And if you run the code you can notice that, Button would have lost it’s total Buttonness Open-mouthed smile ( I invented this word).

You can notice that Button would do its work and fires a click event, but you no longer see the visual transition and the hover effect of a typical button.

This is the way template is defined. It overrides all the properties.

But there’s a way to handle that, using the Content Presenter and Template Binding. Template Binding takes the property values from the control and pass it to the Template (Control Template)

<ControlTemplate x:Key="ContentPresenterButtonTemplate" TargetType="Button"> <Border BorderBrush="BlueViolet" BorderThickness="3" CornerRadius="4" Background="{TemplateBinding Background}"> <ContentPresenter Margin="{TemplateBinding Padding}"></ContentPresenter> </Border> </ControlTemplate>

It is used in a Button like this

<Button Content="Button" Height="41" HorizontalAlignment="Left" Margin="20,101,0,0" Name="button2" Style="{StaticResource ButtonStyle}" Template="{StaticResource ContentPresenterButtonTemplate}" VerticalAlignment="Top" Width="166" Padding="10" /

Output

image

You can see the value set on the Style is applied for Background. And Content Presenter wraps the content of a control which also used Template Binding, so the Content value in the Button is used.

Advertisement