Theming in Silverlight

A good design is appreciated if the look and feel is consistent across the application or site you develop. The first and the most best,popular option that comes to our minds is "Themes".

Silverlight allows developers to create rich styles for controls.
Every style has a unique key to identify and it is targeted for a particular element.
To apply style to an element,you have to bind it’s Style property with the unique key of the style defined in the resources at application or local level or defined in resource dictionary.

But is it possible to avoid inline (StaticResource) binding of styles and implicitly apply them to all elements going by the concept of "Themes".
The answer is "YES" and here is the solution. 

How to go about.  ?
In addition to Silverlight library, you will have to install the Silverlight toolkit.
The latest release is here.
There are inbuild themes already available in Silverlight toolkit,but I will create a simple theme from scratch.

Here are the steps:
1) Open Visual Studio and select a Silverlight application.

Silverlight application
2) Add a new folder "Themes" to the project.
Add three Silverlight resource dictionaries each for red,blue and green theme. Set the "Build Action" to Content for each xaml resource file in properties panel ,so that they are added to .xap file and they can be relatively located.

Silverlight resource dictionary       Project structure

Setting the build action to content

 

3) Add reference to "System.Windows.Controls.Theming".
Adding System.Windows.Controls.Theming to the project

4) In MainPage.xaml, I have added a ListBox with names of colors as ListBoxItems.
In a Stackpanel elements like Button,TextBlock and RadioButton have been added.
What I wish to do is on selecting a particular color from ListBox, I want the themes to be applied to all the elements in the StackPanel without StaticResource binding. But first let us create styles for a every element for red,green and blue themes respectively.

Elements in MainPage.xaml file

Code in MainPage.xaml file.

<UserControl x:Class="Themes_Application.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"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot"  HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListBox x:Name="lstThemeColor" SelectionChanged="lstThemeColor_SelectionChanged" Width="Auto" BorderBrush="Black" BorderThickness="1" Height="Auto" Grid.Row="0">
            <ListBoxItem Content="Red"/>
            <ListBoxItem Content="Blue"/>
            <ListBoxItem Content="Green"/>
        </ListBox>

        <StackPanel Grid.Row="1" Orientation="Horizontal" x:Name="pnlElements" >
            <Button Height="50" Width="100" Content="Button1" Margin="5"/>
            <Button Height="50" Width="100" Content="Button2" Margin="5"/>
            <Button Height="50" Width="100" Content="Button3" Margin="5"/>
            <TextBlock Text="TextBlock1" Width="Auto" Height="30" Margin="5"/>
            <TextBlock Text="TextBlock2" Width="Auto" Height="30" Margin="5" />
            <RadioButton Content="RadioButton1" Width="Auto" Height="30" Margin="5"/>
            <RadioButton Content="RadioButton2" Width="Auto" Height="30" Margin="5"/>
        </StackPanel>

    </Grid>
</UserControl>

5) The best way to create styles is to copy the xaml code created in Expression Blend after right clicking the element and selecting the "Edit Template" option. Expression Blend provides excellent options to create styles. Change the color properties and edit the states for a particular control. Click here “http://www.silverlight.net/learn/tutorials/stylestemplatesvsm-cs/” to learn how to create styles,templates.
After copy-pasting styles for different colors in resource dictionary, remove the "x:Key" property from every style created  for a particular control as it is not required. Your “RedTheme.xaml ” will look like this. Similary there will be styles created for every type of element in BlueTheme.xaml and GreenTheme.xaml files.

Code in RedTheme.xaml file

6) Once the styles are in place ,we now write the logic to apply it to the elements in the StackPanel. The code is written in MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;

//this reference is required…
using System.Windows.Controls.Theming;

namespace Themes_Application
{
    public partial class MainPage : UserControl
    {
        Uri uri_resource;
        public MainPage()
        {
            InitializeComponent();
        }

        //on selecting a color value the theme should be applied.
        private void lstThemeColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string color_name = ((ListBoxItem)(lstThemeColor.SelectedItem)).Content.ToString();
            if (color_name == "Red")
            {
                uri_resource = new Uri("Themes/RedTheme.xaml", UriKind.Relative);
            }
            else if (color_name == "Blue")
            {
                uri_resource = new Uri("Themes/BlueTheme.xaml", UriKind.Relative);
            }
            else if (color_name == "Green")
            {
                uri_resource = new Uri("Themes/GreenTheme.xaml", UriKind.Relative);
            }

            //get the theme file and apply it to elements in panel.
            ImplicitStyleManager.SetResourceDictionaryUri(pnlElements, uri_resource);
            ImplicitStyleManager.SetApplyMode(pnlElements, ImplicitStylesApplyMode.Auto);
            ImplicitStyleManager.Apply(pnlElements);
        }
    }
}

Here the ImplicitStyleManager is a class that provides methods to do the following tasks.

a) To first locate the resource dictionary which will apply styles to elements. Here it is the xaml files stored in “Themes” folder
b) To get the name of the parent element in which the child controls or descendants have to be applied styles.
c) To implicitly apply styles to the parent element and its descendants.

Thus without doing any StaticResource binding to any of the elements you can create Themes and apply them implicitly.
Here is the final output in browser.

      Green theme applied

       BlueTheme applied

Red Theme applied

Behaviors and Actions in Blend3

Behaviors add interactivity to your application without having to write any code.
They are reusable pieces of packaged code that can be dragged onto any object to change its own or
other object’s properties,control storyboards ,change layout properties etc..
Behaviors  not necessarily be invoked by triggers,they work when some conditions are met.

An Action is an object that can do something..
A Trigger reacts to the cause and invokes one or more Actions.

Expression Blend 3 provides by default some behaviors and Actions in the asset panel…..

Behaviours and Actions in Asset Panel

Behaviours and Actions in Asset Panel

Here are some examples:

1) ControlStoryBoardAction: Lets u play,start,stop,pause a storyboard.
Here the storyboard animates the width property of a rectangle on click event of Button.
You have to drag the ControlStoryBoardAction on to your button and set the properties.

Setting properties for ControlStoryBoardAction

Setting properties for ControlStoryBoardAction

Storyboard

Storyboard

Code for animating the width of an ellipse on click of button

Code for animating the width of an ellipse on click of button

2) ChangePropertyAction: Changes the property and lets u animate it over some duration.
Here the opacity of the ellipse varies on click of the button.
Drag the action on button and set the properties.
There are options available to ease in and ease out your animation…over time.

Setting properties for ChangePropertyAction

Setting properties for ChangePropertyAction

Button nd ellipse

Code to change the opacity of ellipse on click of button

Code to change the opacity of ellipse on click of button

3) FluidMotionBehaviour: Animates the layout properties of objects in panel.
Here the button flies in from left in the canvas which is its parent container.
You can set the direction of easing in/out in x and y direction with options available in properties panel

Setting properties for FluidMotionbehaviour

Setting properties for FluidMotionbehaviour

Ease in/out options

Ease in/out options

pic11

Code for changing layout properties of button in canvas

Code for changing layout properties of button in canvas

4) MouseDragElementBehaviour:  It lets the object within the parent container to reposition.
Here the ellipse can be dragged within the boundaries of the button.

MouseDragElementBehaviour properties

MouseDragElementBehaviour properties

pic12

Code for moving ellipse in a button

Code for moving ellipse in a button

5) GotoStateAction: Changes to visual state
Here the rectangle and ellipse colliding animation is captured by a state.
This state is transitioned to on click event of a button.

Setting properties of GotoStateAction

Setting properties of GotoStateAction


pic13

Push state code including storyboard to animate

Push state code including storyboard to animate

Code for switching to push state..

Code for switching to push state..

You can also get more behaviors from the Expression Studio site.
Navigate to Expression Gallery to find more behaviors.

Working with Silverlight in Eclipse

Eclipse comes in with a real good development environment for Microsoft Silverlight.
Here’s the link: http://eclipse4sl.org/

The environment works in two modes:
* Pure Eclipse configuration: Wherein you can edit and work with XAML files and in whole Silverlight projects in Eclipse
* Mixed Mode: You can open the solutions created in Eclipse in Visual Studio and Expression Blend also.

For complete installation instructions navigate to:
Installation instructions for Windows and Mac

My applications ran successfully after installing:

  • jdk1.5.0_19
  • Eclipse Ganymede
  • Net Framework 3.5
  • Silverlight 3 runtime
  • Silverlight 3 sdk

Here are some snapshots:

XAML files in Eclipse.

XAML files in Eclipse.

Options to create new project,add xaml files etc..

Options to create new project,add xaml files etc..

Preferences dialog box to set paths for Silverlight SDK,.Net framework..

Preferences dialog box to set paths for Silverlight SDK,.Net framework..VS nd Blend