Mentre in WPF per definire uno stile implicito è sufficiente non utilizzare x:Key nella definizione dello style:

<Style TargetType="{x:Type Button}">
            <!--No key defined!-->
            <Setter Property="Background" Value="Blue" />
            <Setter Property="Foreground" Value="Yellow" />
            <Setter Property="FontSize" Value="22" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Margin" Value="10" />
        </Style>

L'equivalente in Silverlight 2.0 non funziona, ovvero non è possibile creare uno stile implicito in questo modo:

<Style  TargetType="Button">
  <Setter Property="Background" Value="Orange" />
  <Setter Property="Foreground" Value="White" />
</Style>

inoltre mentre in WPF scrivere TargetType="{x:Type Button}" oppure TargetType="Button" è indifferente, in Silverlight 2.0 solo la seconda modalità è supportata.
Supponiamo ora di creare una nuova classe MyButton che eredita da Button e, dopo avere importato il relativo namespace in XAML, aggiungiamolo al Visual Tree della nostra finestra nel caso WPF oppure dello UserControl se usate Silverlight.

Type
namespace DefaultTemplate
{
    public class MyButton:Button{}
}
 
Page.xaml
<UserControl x:Class="DefaultTemplate.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DefaultTemplate;assembly=DefaultTemplate"
    Width="400" Height="300">
    <StackPanel x:Name="LayoutRoot" Background="White">
        <Button  Margin="20" Content="Button1" />
        <local:MyButton Margin="20" Content="Button2" />
        <local:MyButton Margin="20" Content="Button3" />
        <Button Margin="20" Content="Button4" />
    </StackPanel> 
</UserControl>

Mentre il WPF il risultato è quello di vedere i 4 pulsanti, in Silverlight quello che otteniamo è visibile in fig.1, ovvero Silverlight ,a differenza di WPF, non eredita il default template della classe base

image  fig.1

A questo punto non ci rimane che definire un nuovo template e associarlo mediante style esplicitamente.

Style

<Application xmlns="http://schemas.microsoft.com/client/2007"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:local="clr-namespace:DefaultTemplate;assembly=DefaultTemplate"
             x:Class="DefaultTemplate.App">
    <Application.Resources>
        <Style x:Key="MyButtonStyle" TargetType="local:MyButton">
            <Setter Property="Background" Value="Orange" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:MyButton">
                        <Grid x:Name="RootElement" >
                            <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" 
                            Background="{TemplateBinding Background}" CornerRadius="5,5,5,5" />
                            <ContentPresenter 
                        Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" 
                        Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

Page.xaml

<StackPanel x:Name="LayoutRoot" Background="White">
   <Button Margin="20" Content="Button1" />
   <local:MyButton Style="{StaticResource MyButtonStyle}" Margin="20" Content="Button2" />
   <local:MyButton Margin="20" Content="Button3" />
   <Button Margin="20" Content="Button4" />
</StackPanel> 

Ottenendo come risultato:

image fig.2

...e se volessimo evitare di dover associare manualmente lo style ovvero creare uno stile implicito in Silverlight?
In questo caso è necessario aggiungere al progetto un nuovo file xaml contenente un ResourceDictionary chiamandolo generic.xaml, non essendo ancora disponibile il template ResourceDictionary potete aggiungere uno UserControl e modificarlo in questo modo:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DefaultTemplate;assembly=DefaultTemplate">
        <Style TargetType="local:MyButton">
            <Setter Property="Background" Value="Yellow" />
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:MyButton">
                        <Grid x:Name="RootElement" >
                            <Ellipse Width="{TemplateBinding Width}" 
                                Height="{TemplateBinding Height}" 
                                Fill="{TemplateBinding Background}"
                            />
                            <ContentPresenter 
                            Content="{TemplateBinding Content}" 
                            ContentTemplate="{TemplateBinding ContentTemplate}" 
                            Foreground="{TemplateBinding Foreground}" 
                            VerticalAlignment="Center" HorizontalAlignment="Center"
                            />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>    
    </ResourceDictionary>

A differenza di WPF, il file generic.xaml non deve stare in una cartella \themes.
Rieseguendo la pagina precedente il risultato sarà:

image  fig.3
Se vi state chiedendo: Ma non si può fare la stessa cosa di WPF ovvero definire uno stile implicito semplicemente omittendo la relativa Key senza ricorrere al file generic.xaml la risposta è: Al momento No.

Se volete approfondire l'aspetto stili in WPF vi rimando a questo articolo.

OK, ora posso organizzare la partenza per il Summit 2008 smile_regular

Technorati Tags: ,