Blog

Styles in Silverlight: an Introduction

This article is part 1 of (planned) 4 in a series attempting to cover everything I think is worth knowing about styles in Silverlight 4.

What are Styles?

Styles in Silverlight are a powerful mechanism that allow controlling the visual representation of elements in a unified way for all user interface elements. The concept is similar to using CSS to control the look and feel of HTML.

Style properties differ by element type. For example on a TextBlock (a text element) one can style the FontSize, FontFamily, Foreground and lots of other properties. On an Ellipse however none of these properties can be set, on the other hand it does provide for example the Fill property, that the TextBlock does not. So creating a blue "Hello, World" text and a red ellipse could be done the following way:

<stackPanel Orientation="Vertical">
     <textBlock FontSize="16" FontFamily="Comic Sans MS" Foreground="Blue">Hello, World!</textBlock>
     <ellipse Fill="Red" Width="30" Height="30"/>
</stackPanel>

However, to do the same thing, we could simply define Styles. Styles are list of property-value pairs. Creating the same blue text and red ellipse with styles would be done the following way:

<userControl.Resources>
    <style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
        <setter Property="FontSize" Value="16"/>
        <setter Property="FontFamily" Value="Comic Sans MS"/>
        <setter Property="Foreground" Value="Blue"/>
    </style>
    <style x:Key="CustomEllipseStyle" TargetType="Ellipse">
        <setter Property="Width" Value="30"/>
        <setter Property="Height" Value="30"/>
        <setter Property="Fill" Value="Red"/>
    </style>
</userControl.Resources>
<stackPanel Orientation="Vertical">
    <textBlock Style="{StaticResource CustomTextBlockStyle}">Hello, World!</textBlock>
    <ellipse Style="{StaticResource CustomEllipseStyle}"/>
</stackPanel>

As you can see properties that we've specified as attributes on the elements, we've listed in the styles and then applied this style to the element. So instead of defining FontSize="16" of the TextBlock, we've added a Setter that had FontSize set as it's Property and 16 as it's Value. (Download the source of this example here: What Are Styles.zip)

Having seen a simple example of using styles, let's look a little bit deeper in to what they actually are.

Styles: List of Setters for a Given Type

Styles are objects that have two important properties: the type that they are applied to (TargetType) and the list of their Setters.

TargetType

Whenever declaring a Style it is mandatory to set it's TargetType, that is which type of visual element it should be applied to. The reason for this is simple: in Silverlight all visual elements have different properties that can be styled. Looking at the previous example, the Style for TextBlock sets different properties than the one for Ellipse.

Because the TargetType has to be set for each style, this means that if you have e.g. a TextBox, an Ellipse and a Grid on the same page, you want all of them to have a blue background or fill, you have to declare three different styles for this:

<userControl.Resources>
    <style x:Key="BlueEllipseStyle" TargetType="Ellipse">
        <setter Property="Fill" Value="Blue"/>
    </style>
    <style x:Key="BlueTextBoxStyle" TargetType="TextBox">
        <setter Property="Background" Value="Blue"/>
    </style>
    <style x:Key="BlueGridStyle" TargetType="Grid">
        <setter Property="Background" Value="Blue"/>
    </style>
</userControl.Resources>

 

Download the source for this example here: Styles - TargetType.zip.

(There are times when you can get away with using the same style for different types, I'll go deeper in this in a later part of the series).

Setters

Setters are the list of property-value pairs. For each type, the Property values of the Setters within the Style must match the properties on the type itself. So for example when styling a TextBlock, you can declare a Setter with the FontSize property, but not the Fill, because TextBlock does not have a Fill property. So the following example would work fine:

<style x:Key="ValidTextBlockStyleExample" TargetType="TextBlock">
    <setter Property="FontSize" Value="16"/>
</style>

However the following declaration would throw a XamlParseException in runtime with the message "The property 'Fill' was not found in type 'System.Windows.Controls.TextBlock'" as there's no FIll property on the TextBlock":

<style x:Key="InValidTextBlockStyleExample" TargetType="TextBlock">
    <setter Property="Fill" Value="Blue"/>
</style> 

Unfortunately at the moment Visual Studio 2010 doesn't have Intellisense support when declaring Setters for styles: so you only get warnings for invalid Setters in runtime. Therefore it's worth double checking that correct Setter properties have been declared.

Defining Styles In XAML

In all of the examples I've defined styles in XAML: declaring them in XAML is the easiest way to write and read them (the other option is to declare them in the code behind, I'll be covering this in a later part of the series). When declaring styles in XAML, one can do it in two different ways: either within Resources section of the XAML or inline.

Defining Styles in the Resources Section

Defining styles in the Resources section is the most common way of doing. For a UserControl(such as the MainPage created as the start page for a new Silverlight application) this means the UserControl.Resources section, that should be declared as child of the UserControl element:

<userControl x:Class="IntroductionToStyles.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <userControl.Resources>
        <style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
            <setter Property="FontSize" Value="16"/>
            <setter Property="FontFamily" Value="Comic Sans MS"/>
            <setter Property="Foreground" Value="Blue"/>
        </style>
    </userControl.Resources>
    <!-- Declare the visual layout after the UserControl.Resources section -->
    <grid x:Name="LayoutRoot"></grid>

When declaring Styles in the Resources section, the x:Key value is required to be set on all Styles (except when applying implicit Styles, which I'll be covering in the next part of the series). The x:Key value defines the key of the style that it can be later referenced as a StaticResource:

<textBlock Style="{StaticResource CustomTextBlockStyle}">Hello, World!</textBlock>

The x:Key values have to be unique within a resource, otherwise a XamlParseException will be thrown with the message "The dictionary key 'xxx' is already used. Key attributes are used as keys when inserting objects into a dictionary and must be unique."

Defining Styles Inline

Defining styles in the Resources section is recommended because that way they can easily be reused within the document by referencing them as StaticResources. However Styles can also be declared as the property of the visual elements. For example, declaring the original example (the blue text and red ellipse) inline would look the following:

 <stackPanel Orientation="Vertical">
    <textBlock>
        <textBlock.Style>
                <style TargetType="TextBlock">
                <setter Property="FontSize" Value="16"/>
                <setter Property="FontFamily" Value="Comic Sans MS"/>
                <setter Property="Foreground" Value="Blue"/>
            </style>
        </textBlock.Style>
        Hello, World!
    </textBlock>
    <ellipse>
        <ellipse.Style>
            <style TargetType="Ellipse">
                <setter Property="Width" Value="30"/>
                <setter Property="Height" Value="30"/>
                <setter Property="Fill" Value="Red"/>
            </style>
        </ellipse.Style>
    </ellipse>
</stackPanel>

Defining styles inline has no real practical usage: it's much more longer to write out than just declaring the properties on the elements and the styles can't even be reused as they're not defined as resources. (Download the source for this example here: Inline Styles.zip)

Referencing Styles Defined in XAML from Code Behind

Styles defined within the Resources section of XAML can be referenced by their x:Key values from the Resources array. So for example referencing the following style defined in XAML:

    <userControl.Resources>
        <style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
            <setter Property="FontSize" Value="16"/>
            <setter Property="FontFamily" Value="Comic Sans MS"/>
            <setter Property="Foreground" Value="Blue"/>
        </style>
    </userControl.Resources>

Can be done the following way in the code behind:

Style customTextBlockStyle = Resources["CustomTextBlockStyle"] as Style;

(Styles can be assigned to objects and manipulated in code behind as well. I'll go into details on this in a later part of the series).

Styling Controls Can't Always Be Done With Styles: Templates and Themes

When working with built-in Silverlight controls, one quickly realizes that styling them doesn't quite work just by using styles. Let's take a Button for example. The default Button implementation has a white color with black text on it. Let's say we want to change it to black background and red text. The Button has both a Background property and a Foreground, so let's set these:

<userControl.Resources>
   <style x:Key="CustomButtonStyle" TargetType="Button">
      <setter Property="Foreground" Value="Red"/>
      <setter Property="Background" Value="Black"/>
</userControl.Resources>
<button Style="{StaticResource CustomButtonStyle}" Content="Click me!" Width="150" Height="30"/>

 

The result:

The button's text color did indeed change to red as we've expected, however the background is still white. This is because the Button control has a much more complex layout than what could be manipulated using simply the Background property. It has gradient fills, different states on mouseover state and when disabled and the designers of this control didn't bother specifying porperties to set each of these. Instead if one wants to customize the look and feel of a Button control (or any other built in Silverlight control), one must either customize it using Control Templates or by using Silverlight Toolkit Themes.

This series focuses only on working with Styles, therefore these topics are out of scope at this point. For further reading on this topic I'd recommend the following articles: Control Templates: a tutorial by Scott Guthrie and Using Silverlight Toolkit Themes by Deborah Kurata.

Conclusion

In this part I've given an overview of what styles are in Silverlight and how they can be used. Main points covered were:

  • Styles are collections of property setters (Setters) to be applied to a visual element. It is mandatory to specify the TargetType for each Style: the type of element it will be applied to.
  • Setters within a Style can be different for styles with different TargetTypes. Setters can only contain propeties that the type to be applied to has as well, otherwise an exception is thrown.
  • Defining styles within XAMLcan be done two ways: either within the Resources section or inline.
    • Defining styles within the Resources section is recommended. Styles defined here need to specify an x:Key attribute and can be reused within the document with StaticResources. Keys need to be unique within a resource section.
    • Inline declaration does not have real advantages: it's lengthy and the Style declared can't be re-used from the XAML.
  • Styles defined in XAML (within the Resources section) can be referenced from code behind
  • The visual look of controls can't always be altered just by setting properties of the control via styles. A more powerful way of customizing control look and feel is via Control Templates and Themes.

I hope this part has been a useful introduction. In the second part of the series I'll be looking into more advanced Style usage scenarios, stay tuned!

Interested in an easy to style, performant Silverlight / WPF charting library? Give the free version of Visiblox a try!

Comments

Well Done!

 
Posted by Michael Washington

Pretty good overview! I will be waiting for the next parts. Thanks

 

[...] Styles?Styles are basically list of property-value pairs. Defining a style consists declaring the TargetType property and the list of [...]

 

[...] 1. Styles in Silverlight: an Introduction Gergely Orosz has blogged about the part 1 of the 4-part series on everything about Styles in Silverlight [...]

 

[...] Styles in Silverlight: an Introduction [...]

 

[...] Styles in Silverlight: an Introduction [...]

 
Nice article , thanks a lot
 
Posted by Thanks for the tutorial but in future also like to see Styling a chart , Linear and Radial Styling

Post a comment