If I had a dollar for every time a developer has said to me “You mean a style can only be applied to an object once in Silverlight? How brain dead!” or “Why doesn’t Silverlight support BasedOn styles like WPF?”, I’d be retired on a tropical island with my own private runway and a fleet of radio-controlled jets. So maybe I exaggerate. Nevertheless, developers will love the style-related enhancements coming in Silverlight 3, which include:

  • Support for BasedOn styles (style inheritance)
  • Support for dynamic styling and skinning (styles can be applied more than once) 
  • Support for merged resource dictionaries

The sample application pictured below demonstrates all three facets of Silverlight 3’s new and improved style story:

Stylin'!!! 

Here’s how you can build the application and experience these enhancements yourself. Begin by creating a new Silverlight 3 project and adding the following declarations to MainPage.xaml:

<StackPanel Orientation=”Vertical” VerticalAlignment=”Center”>

  <Button x:Name=”SampleButton” Content=”Sample Button”

    Width=”300″ Height=”200″ FontSize=”24″ />

  <RadioButton x:Name=”UnstyledOption” Content=”Unstyled” FontSize=”20″

    Width=”260″ Margin=”0,36,0,0″ IsChecked=”True” Click=”RadioButton_Click” />

  <RadioButton x:Name=”BlurredOption” Content=”Blurred” FontSize=”20″

    Width=”260″ Click=”RadioButton_Click” />

  <RadioButton x:Name=”RotatedOption” Content=”Rotated” FontSize=”20″

    Width=”260″ Click=”RadioButton_Click” />

  <RadioButton x:Name=”BlurredRotatedOption” Content=”Blurred and Rotated”

    FontSize=”20″ Width=”260″ Click=”RadioButton_Click” />

</StackPanel>

Now add the following event handler to the MainPage class in MainPage.xaml.cs:

private void RadioButton_Click(object sender, RoutedEventArgs e)

{

    string name = ((FrameworkElement)sender).Name;

 

    switch (name)

    {

        case “UnstyledOption”:

            SampleButton.Style = null;

            break;

 

        case “BlurredOption”:

            SampleButton.Style = (Style)Application.Current.Resources[“Blurred”];

            break;

 

        case “RotatedOption”:

            SampleButton.Style = (Style)Application.Current.Resources[“Rotated”];

            break;

 

        case “BlurredRotatedOption”:

            SampleButton.Style = (Style)Application.Current.Resources[“BlurredAndRotated”];

            break;

    }

}

Observe that this event handler programmatically applies global styles to a Button control. We need to define those styles, so go to App.xaml and add the following XAML to <Application.Resources>:

<ResourceDictionary>

  <ResourceDictionary.MergedDictionaries>

    <ResourceDictionary Source=”Styles.xaml” />

  </ResourceDictionary.MergedDictionaries>

  <Style x:Key=”Blurred” TargetType=”Button”>

    <Setter Property=”Effect”>

      <Setter.Value>

        <BlurEffect Radius=”8″ />

      </Setter.Value>

    </Setter>

  </Style>

  <Style x:Key=”BlurredAndRotated” TargetType=”Button”

    BasedOn=”{StaticResource Blurred}”>

    <Setter Property=”RenderTransform”>

      <Setter.Value>

        <RotateTransform Angle=”10″ />

      </Setter.Value>

    </Setter>

  </Style>

</ResourceDictionary>

One of the styles used in the application is defined external to App.xaml in Styles.xaml. (Note the Source attribute attached to the ResourceDictionary element.) Add a new file named Styles.xaml to your Silverlight project. Set its build action to “Resource” and add the following XAML to it:

<ResourceDictionary

  xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

  xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

  <Style x:Key=”Rotated” TargetType=”Button”>

    <Setter Property=”RenderTransform”>

      <Setter.Value>

        <RotateTransform Angle=”10″ />

      </Setter.Value>

    </Setter>

  </Style>

</ResourceDictionary>

Now build the project and you’re ready to go. Each time you click a radio button, a style is programmatically applied to the Button control—something that you couldn’t do more than once in Silverlight 2. One of the styles—the one named “BlurredAndRotated”—is a BasedOn style that adds a RenderTransform setter to the Effect setter defined in the “Blurred” style. Finally, the “Rotated” style is defined externally in Styles.xaml and imported into App.xaml. Stylin’!

To be sure, there is still a gap between the style support in Silverlight and the style support in WPF. Silverlight still does not, for example, support implicit styles or style triggers, but hey! The team has to save something for Silverlight 4. 🙂