Silverlight 4 Rough Notes: Styles

Note – these posts are put together after a short time with Silverlight 4 as a way of providing pointers to some of the new features that Silverlight 4 has to offer. I’m posting these from the PDC as Silverlight 4 is announced for the first time so please bear that in mind when working through these posts.

There are some new additions around Styles when it comes to Silverlight 4. As in WPF, it’s now possible to style all controls of a particular type.

For example, all buttons in one of these grids will be Blue whereas all buttons in the other will be red;

<UserControl x:Class="SilverlightApplication14.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:DesignHeight="300" d:DesignWidth="400">

    <StackPanel
        x:Name="layoutRoot">
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button">
                    <Setter
                        Property="Background"
                        Value="Blue" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 1" />
            <Button
                Grid.Row="1"
                Content="Button 2" />
        </Grid>
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button">
                    <Setter
                        Property="Background"
                        Value="Red" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 3" />
            <Button
                Grid.Row="1"
                Content="Button 4" />
        </Grid>
    </StackPanel>

</UserControl>

image

Note that the Styles in question do not have x:Keys on them which makes them implicit styles and so they apply to all controls of the specified type within their scope and so you could e.g. style all buttons at the application level without having to specify a Style property on the button.

If I have multiple implicit styles relating to a particular control then they do not magically combine so, for instance, if I have a new style here at the UserControl level which is trying to make all the FontSize values equal to 36;

view plaincopy to clipboardprint
<UserControl x:Class="SilverlightApplication14.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:DesignHeight="300" d:DesignWidth="400">  
       
    <UserControl.Resources>  
        <Style  
	TargetType="Button">  
            <Setter  
                Property="FontSize"  
                Value="36" />  
        </Style>  
    </UserControl.Resources>  
  
    <StackPanel  
        x:Name="layoutRoot">  
        <Grid  
            Background="White">  
            <Grid.Resources>  
                <Style  
                    TargetType="Button">  
                    <Setter  
                        Property="Background"  
                        Value="Blue" />  
                </Style>  
            </Grid.Resources>  
            <Grid.RowDefinitions>  
                <RowDefinition />  
                <RowDefinition />  
            </Grid.RowDefinitions>  
            <Button  
                Content="Button 1" />  
            <Button  
                Grid.Row="1"  
                Content="Button 2" />  
        </Grid>  
        <Grid  
            Background="White">  
            <Grid.Resources>  
                <Style  
                    TargetType="Button">  
                    <Setter  
                        Property="Background"  
                        Value="Red" />  
                </Style>  
            </Grid.Resources>  
            <Grid.RowDefinitions>  
                <RowDefinition />  
                <RowDefinition />  
            </Grid.RowDefinitions>  
            <Button  
                Content="Button 3" />  
            <Button  
                Grid.Row="1"  
                Content="Button 4" />  
        </Grid>  
    </StackPanel>  
  
</UserControl>  

then that won’t get combined with the more local implicit styles and the font-sizes will stay unaffected. Implicit styles can still use BasedOn though so I could make what I want work by doing;

<UserControl x:Class="SilverlightApplication14.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:DesignHeight="300" d:DesignWidth="400">
    
    <UserControl.Resources>
        <Style
            x:Key="myStyle" TargetType="Button">
            <Setter
                Property="FontSize"
                Value="36" />
        </Style>
    </UserControl.Resources>

    <StackPanel
        x:Name="layoutRoot">
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button"
                    BasedOn="{StaticResource myStyle}">
                    <Setter
                        Property="Background"
                        Value="Blue" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 1" />
            <Button
                Grid.Row="1"
                Content="Button 2" />
        </Grid>
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button"
                    BasedOn="{StaticResource myStyle}">
                    <Setter
                        Property="Background"
                        Value="Red" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 3" />
            <Button
                Grid.Row="1"
                Content="Button 4" />
        </Grid>
    </StackPanel>

</UserControl>

and then I get the combination that I was looking for;

image

Similarly, if a control has an explicitly stated style then it does not pick up anything from the implicit style. For example, if I give Button 4 an explicit style;

<UserControl x:Class="SilverlightApplication14.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:DesignHeight="300" d:DesignWidth="400">
    
    <UserControl.Resources>
        <Style
            x:Key="myStyle" TargetType="Button">
            <Setter
                Property="FontSize"
                Value="36" />
        </Style>
    </UserControl.Resources>

    <StackPanel
        x:Name="layoutRoot">
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button"
                    BasedOn="{StaticResource myStyle}">
                    <Setter
                        Property="Background"
                        Value="Blue" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 1" />
            <Button
                Grid.Row="1"
                Content="Button 2" />
        </Grid>
        <Grid
            Background="White">
            <Grid.Resources>
                <Style
                    TargetType="Button"
                    BasedOn="{StaticResource myStyle}">
                    <Setter
                        Property="Background"
                        Value="Red" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button
                Content="Button 3" />
            <Button
                Grid.Row="1"
                Content="Button 4"
                Style="{StaticResource myStyle}"/>
        </Grid>
    </StackPanel>

</UserControl>

then it no longer picks up anything ( specifically the background colour of Red ) from the implicit style;

image

and goes back to using the standard background colour.

I think this is a great addition to styling – it’s something that WPF has been able to do since the first version and I’ve always missed having it in Silverlight. You can define implicit styles at any level from the application down and so take much easier control over the “default” look and feel for the application without having to clutter every definition with Style={}.