Toolkit release & Themes

 

Today at Microsoft PDC, Scott Guthrie demonstrated some of the new controls that have been provided as a part of the Silverlight Toolkit

The Silverlight Toolkit was previously named the Silverlight Control Pack

This toolkit provides a set of controls and themes for Silverlight 2. 

  • AutoCompleteBox
  • Chart
  • DockPanel
  • Label
  • Expander
  • TreeView
  • UpDown
  • ViewBox
  • WrapPanel
  • ImplicitStyleManager

These controls and their source code are available with Ms-Pl licensing on Codeplex

Historically, charting has been an extra-cost item, provided by third party vendors, but the Silverlight team is providing an extensive and extensible set of chart controls, with source code for free. We will be creating numerous HDI videos and tutorials to assist with getting the most from these controls and Tim has already posted a mini-tutorial to get you started.

I’ll kick of an examination of themes with a very simple application. To get started add the theme dll references to your application

ThemesDLLs

Note that for convenience, I’ve chosen to put my Controls dlls into a subdirectory of C:\Program Files (x86)\Microsoft SDKs\Silverlight\v2.0 though this is not required.

You can now add a theme either in Blend or in Visual Studio. Let’s start in Blend, but also look in Visual Studio to see how the Xaml is placed and, at least at the most superficial level, what the Theme does for you.

Themes in Blend

Once the themes are in your references, you can treat them as controls by extending the chevron, clicking on “show all” and choosing “custom controls” (remember, these controls are not in the core).

AssetLibraryThemes

You can add a theme to your page just as you add any control. typically, you will want to add a theme to a high level FrameworkElement, as all of the children (contained controls) will be themed.

Once you add the theme, you’ll want to double click on it, making it the container, so that additional controls will be “within” the theme, and thus the theme will be applied to those controls.

Within that theme can be one control, but of course that control can be (and should typically be) a container control, and so we end up with something like this,

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="ThemesTest.Page"
   5:     Width="800" Height="600" 
   6:     xmlns:shinyRed="clr-namespace:Microsoft.Windows.Controls.Theming;assembly=Microsoft.Windows.Controls.Theming.ShinyRed" 
   7:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   8:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   9:     mc:Ignorable="d">
  10:  
  11:     <Grid x:Name="LayoutRoot" Background="White">
  12:         <shinyRed:ShinyRedTheme HorizontalAlignment="Stretch" Margin="0" Width="Auto" 
  13:          FontFamily="Verdana" FontSize="24" FontWeight="Bold">
  14:             <Grid Height="Auto" x:Name="InnerGrid" Width="Auto">
  15:               <Grid.ColumnDefinitions>
  16:                     <ColumnDefinition Width="0.1*"/>
  17:                     <ColumnDefinition Width="0.1*"/>
  18:                 </Grid.ColumnDefinitions>
  19:  
  20:                 <Button x:Name="btn"
  21:                     Height="72" 
  22:                     HorizontalAlignment="Left" 
  23:                     VerticalAlignment="Bottom" 
  24:                     Width="244" Margin="0" 
  25:                     Content="This button is themed" 
  26:                     FontSize="18"  FontFamily="Verdana"/>
  27:                 <CheckBox 
  28:                     HorizontalAlignment="Left" 
  29:                     VerticalAlignment="Bottom" 
  30:                     Margin="10,0,0,0" 
  31:                     Width="150" Height="50"
  32:                     Content="CheckBox"
  33:                     Grid.Column="1" />
  34:             </Grid>
  35:         </shinyRed:ShinyRedTheme>
  36:     </Grid>    
  37: </UserControl>

Notice that we start with on outer grid, within that grid is a theme and inside that theme is another grid. We’re now back to programming exactly the way we always have; doing nothing special to the controls; but they are created within a theme, and thus the the theme is applied to the button and checkbox,

TwoThemedControls

To get a sense of how this affects a variety of controls, I created a slightly larger application that has two grids, one with a number of controls that are themed, the second with the same controls unthemed.

Here’s the page.xaml,

<UserControl xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="themes1.Page"
Width="700" Height="650" 
xmlns:rainerPurple="clr-namespace:Microsoft.Windows.Controls.Theming;assembly=Microsoft.Windows.Controls.Theming.RainierPurple" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<Grid x:Name="outer">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
    <rainerPurple:RainierPurpleTheme Margin="0,0,0,0"     >
        <Grid x:Name="LayoutRoot" Background="White" Height="600" Width="320" Grid.Column="0" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.1*"/>
                <ColumnDefinition Width="0.1*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.1*"/>
                <RowDefinition Height="0.1*"/>
                <RowDefinition Height="0.8*"/>
            </Grid.RowDefinitions>
            <Button Width="100" Content="Click Me" x:Name="myButton" HorizontalAlignment="Left" FontFamily="Verdana" FontSize="14"  Margin="5,0,0,0" VerticalAlignment="Bottom"/>
            <CheckBox Grid.Column="1" Content="Theme engaged" HorizontalAlignment="Left" IsChecked="True" FontSize="14" FontFamily="Verdana" Margin="5,0,0,0" d:LayoutOverrides="Height" VerticalAlignment="Bottom"/>
            <basics:Calendar DisplayMode="Month" IsTodayHighlighted="True" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" Margin="5,0,0,0" Width="150" VerticalAlignment="Top" />
            <PasswordBox Width="111" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Height="30" Margin="5,0,0,0" VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5" />
            <StackPanel HorizontalAlignment="Stretch" Margin="0,0,0,0"
            Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
                <RadioButton x:Name="rb1" GroupName="Grp1" Content="yes" IsChecked="true" Width="50" Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5,0,0,0" />
                <RadioButton x:Name="rb2" GroupName="Grp1" Content="no" Width="50" Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5,0,0,0" />
            </StackPanel>
            <Button Height="42" Margin="36,82,46,0" VerticalAlignment="Top" Grid.Column="1" Grid.Row="2" Content="Button"/>
        </Grid>
    </rainerPurple:RainierPurpleTheme>
    <Grid x:Name="LayoutRoot2" Background="White" Height="600" Width="320" Grid.Row="0" Grid.Column="1" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.1*"/>
            <ColumnDefinition Width="0.1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.1*"/>
            <RowDefinition Height="0.1*"/>
            <RowDefinition Height="0.8*"/>
        </Grid.RowDefinitions>
        <Button Width="100" Content="Click Me" x:Name="myButton2" HorizontalAlignment="Left" FontFamily="Verdana" FontSize="14" Margin="5,0,0,0" VerticalAlignment="Bottom"/>
        <CheckBox Grid.Column="1" Content="Theme engaged" HorizontalAlignment="Left" IsChecked="True" FontSize="14" FontFamily="Verdana" Margin="5,0,0,0" d:LayoutOverrides="Height" VerticalAlignment="Bottom"/>
        <basics:Calendar DisplayMode="Month" IsTodayHighlighted="True" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" Margin="5,0,0,0" Width="150" VerticalAlignment="Top" />
        <PasswordBox Width="111" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Height="30" Margin="5,0,0,0" VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5" />
        <StackPanel HorizontalAlignment="Stretch" Margin="0,0,0,0"
            Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
            <RadioButton x:Name="rb1a" GroupName="Grp1" Content="yes" IsChecked="true" Width="50" Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5,0,0,0" />
            <RadioButton x:Name="rb2a" GroupName="Grp1" Content="no" Width="50" Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5,0,0,0" />
        </StackPanel>
    </Grid>
</Grid>
erControl>

The output looks like this (adjusted to save space)

twoGridsWithThemes

Note that the theme is in the .dll and not in App.xaml; you are certainly free to add styles and templates on top of these themes. 

As noted this micro-tutorial is only intended to get you started, and not to be comprehensive. Hope it helps.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in z Silverlight Archives. Bookmark the permalink.