Windows Phone Control Styles and Templates

.Custom Control

Custom Control, Own Work

Control Styling

"Styling controls in Silverlight are very similar to the styles used with HTML in Cascading Style Sheets. You can think of a Style as a convenient way to apply a set of property values to more than one element."

  • The Style class enables the grouping of control property values into a reusable resource. This group can then be applied to multiple instances of the same type of control. Styling controls in Silverlight are very similar to the styles used with HTML in Cascading Style Sheets.
    • A Style can be set on any control that derives from FrameworkElement or FrameworkContentElement.
    • However, styles are defined by control type and can not be set to a different type of control. That is, if a style is defined for a TextBox control, is can not be used on a TextBlock control.
    • A style is most commonly declared as a resource inside the Resources section, and obeys the same scoping rules that apply to all resources.
    • The style declaration consists of a Style object that contains a collection of one or more Setter objects. Each Setter consists of a (Property-Value) pair.
  • There are three types of styles:
    1. Explicit - is a style that has a key defined. That is the x:Key directive is defined to identify the style by name.
    2. Implicit - a style that does NOT have a key defined (no x:Key directive defined). So it uses the TargetType property to assign the styles to all the controls of a particular type.
    3. BasedOn - uses the BasedOn attribute to name an explicit style as the base style. The BasedOn style will then inherit all the settings from the base style and additional setting can be added to derive a new style.
Explicit Style with Key (x:key=) Defined

,Explicit Style

Explicit Style, Own Work

Style Scope

"Element Level styles have the highest precedence. If you define a style at the element level no other style will be able to override it."

  • Silverlight styling can be set at three levels. Listed in the order of highest precedence, the levels are:
    1. Element Level - only the specific control element will be affected by the style. Element level styling is coded by putting the style property setting inside the element tag. However, this can become messy when there are multiple elements of the same type which need to have the same style properties.
    2. Page Level - styles are defined in Resource Section of the xaml code for a particular page (eg MainPage.xaml). The style will apply to all the matching controls throughout that particular page.
    3. Global Level - styles are defined in Resource Section of App.xaml and apply to all matching elements throughout the application. Note: The same definitions created in the page xaml can be moved to App.xaml and will then have a global scope.
Page-Level Implicit Style (No Key Defined)
,Page-Level Implicit Style

Page-Level Implicit Style, Own Work

Control Templates

"A control template can be used to completely change the way a control looks; changes beyond what can be made through the control properties."

  • A Control Template specifies the visual structure of a control, which can be shared across multiple instances of the control.
    • A ControlTemplate is intended to be a self-contained unit of implementation detail that is invisible to outside users and objects, including styles.
    • The styling and templating model provides you with such great flexibility that in many cases you do not need to write your own controls.
    • Below is an example of a Button control that has a template to change its appearance to a bulls-eye. The modified control still retains its button behaviors (eg. Click).
Button Control Changed to a Bulls-eye Appearance with Control Template

.Control Template

Button Control Template, Own Work

Control Template Binding

"TemplateBinding is a markup extension. All markup extensions in XAML use the { and } characters in their attribute syntax."

  • TemplateBinding provides a link to the value of a property on a templated control.
    • Below is an example of a button using template binding to obtain the value of the width and height properties from the parent element.
  • Template Binding to obtain Height and Width from Parent Button

,Template Binding,

Template Binding, Own Work


External Styles using a Resource Dictionary

"Increase Re-usability of styles and text resources by defining them in an external resource dictionary, instead of defining them in the same project which uses them."

  • The External styles in Windows Phone article from the Nokia Developer Wiki website describes how to create and reference a Style project, containing a resource dictionary, to allow for consistent and re-usable styles across multiple projects.
    1. Create a new project (Windows Phone Class Library) as a Style project.
    2. Remove the default class file.
    3. Add a ResourceDictionary library file (xaml file) to the project.
    4. Define the styles in the Resource Dictionary file.
    5. To use the ResourceDictionary in another project:
      1. Add a reference to the Resource Dictionary (Reference ->AddReference->Project->Name of Style Project.
      2. In app.xaml, under Application.Resources ... merge the Resource Dictionary with the project resources.



              <ResourceDictionary Source="/ProjectResources;component/StyleResources.xaml" />


      3. Should now be able to use the styles defined in the Style Project in the new project.
  • The following is a code example which used the above procedure to create the Holiday Page application shown in the screen shot above:


Code Example using an External Style Resource Dictionary



StyleResource.xaml (Resource Dictionary)

<ResourceDictionary    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <Style x:Key="HeaderTextStyle"
           TargetType="TextBlock">
        <Setter Property="FontSize"
                Value="36" />
        <Setter Property="FontWeight"
                Value="Bold" />
        <Setter Property="FontFamily"
                Value="Segoe WP" />
        <Setter Property="Foreground"
                Value="White" />
    </Style>
   
    <Style x:Key="NormalTextStyle"
           TargetType="TextBlock">
        <Setter Property="FontSize"
                Value="30" />
        <Setter Property="FontWeight"
                Value="Normal" />
        <Setter Property="FontFamily"
                Value="Segoe WP" />
        <Setter Property="Foreground"
                Value="Yellow" />
    </Style>
    <Style x:Key="GreenLargeTextStyle"
           TargetType="TextBlock">
        <Setter Property="FontSize"
                Value="40" />
        <Setter Property="FontWeight"
                Value="Normal" />
        <Setter Property="FontFamily"
                Value="Segoe WP" />
        <Setter Property="Foreground"
                Value="Green" />
    </Style>
   
    <Style x:Key="RedMediumTextStyle"
           TargetType="TextBlock">
        <Setter Property="FontSize"
                Value="30" />
        <Setter Property="FontWeight"
                Value="Normal" />
        <Setter Property="FontFamily"
                Value="Segoe WP" />
        <Setter Property="Foreground"
                Value="Red" />
    </Style>

    <Style x:Key="BlueSmallTextStyle"
           TargetType="TextBlock">
        <Setter Property="FontSize"
                Value="20" />
        <Setter Property="FontWeight"
                Value="Normal" />
        <Setter Property="FontFamily"
                Value="Segoe WP" />
        <Setter Property="Foreground"
                Value="Blue" />
    </Style>

</ResourceDictionary>

App.xaml (Merge Resource Dictionary)

<Application
    x:Class="ReferenceApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">

    <!--Application Resources-->
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ProjectResources;component/StyleResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Required object that handles lifetime events for the application-->
        <shell:PhoneApplicationService
            Launching="Application_Launching" Closing="Application_Closing"
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
    </Application.ApplicationLifetimeObjects>

</Application>

MainPage.xaml (Use Styles from Resource Dictionary)

<phone:PhoneApplicationPage
    x:Class="ReferenceApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="Kevin's Holiday App" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="Holiday Page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            <TextBlock Text="Merry Christmas!"
                       Style="{StaticResource GreenLargeTextStyle}"
                       Margin="20,20,0,0"
                       TextAlignment="Center" />
            <TextBlock Text="and"
                       Style="{StaticResource BlueSmallTextStyle}"
                       Margin="20,20,0,0"
                       TextAlignment="Center" />
            <TextBlock Text="Happy New Year!"
                       Style="{StaticResource RedMediumTextStyle}"
                       Margin="20,20,0,0"
                       TextAlignment="Center" />
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
    </Grid>

    <!--Sample code showing usage of ApplicationBar-->
    <!--<phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>


Reference Articles