Come creare uno stile per un controllo (WPF .NET)

Con Windows Presentation Foundation (WPF), è possibile personalizzare l'aspetto di un controllo esistente con il proprio stile riutilizzabile. Gli stili possono essere applicati a livello globale all'app, alle finestre e alle pagine o direttamente ai controlli.

Importante

La documentazione di Desktop Guide per .NET 7 e .NET 6 è in fase di costruzione.

Creare uno stile

È possibile considerare un Style oggetto come un modo pratico per applicare un set di valori di proprietà a uno o più elementi. È possibile usare uno stile su qualsiasi elemento che deriva da FrameworkElement o FrameworkContentElement , ad esempio , Window o Button.

Il modo più comune per dichiarare uno stile è una risorsa nella Resources sezione di un file XAML. Poiché gli stili sono risorse, obbediscono alle stesse regole di ambito applicabili a tutte le risorse. Basta, dove dichiari uno stile influisce sulla posizione in cui è possibile applicare lo stile. Ad esempio, se dichiari lo stile nell'elemento radice del file XAML di definizione dell'app, lo stile può essere usato ovunque nella tua app.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Se dichiari lo stile in uno dei file XAML dell'app, lo stile può essere usato solo in tale file XAML. Per altre informazioni sulle regole di definizione dell'ambito per le risorse, vedere Panoramica delle risorse XAML.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        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"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Uno stile è costituito da <Setter> elementi figlio che impostano le proprietà sugli elementi a cui viene applicato lo stile. Nell'esempio precedente si noti che lo stile è impostato per l'applicazione ai TextBlock tipi tramite l'attributo TargetType . Lo stile imposta su FontSize e su FontWeightExtraBold.15 Aggiungere un oggetto <Setter> per ogni proprietà modificata dallo stile.

Applicare uno stile in modo implicito

Un Style è un modo pratico per applicare un set di valori di proprietà a più di un elemento. Si considerino, ad esempio, gli elementi seguenti TextBlock e l'aspetto predefinito in una finestra.

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Styling sample screenshot before

È possibile modificare l'aspetto predefinito impostando le proprietà, ad esempio FontSize e FontFamily, in ogni TextBlock elemento direttamente. Tuttavia, se vuoi che gli TextBlock elementi convidano alcune proprietà, puoi creare un oggetto Style nella Resources sezione del file XAML, come illustrato di seguito.

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Quando imposti lo TargetType stile sul TextBlock tipo e ometti l'attributo x:Key , lo stile viene applicato a tutti gli TextBlock elementi con ambito allo stile, che in genere è il file XAML stesso.

Ora gli TextBlock elementi vengono visualizzati nel modo seguente.

Styling sample screenshot base style

Applicare uno stile in modo esplicito

Se si aggiunge un x:Key attributo con valore allo stile, lo stile non viene più applicato in modo implicito a tutti gli elementi di TargetType. Solo gli elementi che fanno riferimento in modo esplicito allo stile avranno lo stile applicato.

Ecco lo stile della sezione precedente, ma dichiarato con l'attributo x:Key .

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Per applicare lo stile, impostare la Style proprietà sull'elemento x:Key sul valore usando un'estensione di markup StaticResource, come illustrato di seguito.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Si noti che al primo TextBlock elemento è applicato lo stile mentre il secondo elemento TextBlock rimane invariato. Lo stile implicito della sezione precedente è stato modificato in uno stile che ha dichiarato l'attributo x:Key , ovvero l'unico elemento interessato dallo stile è quello che ha fatto riferimento direttamente allo stile.

Styling sample screenshot textblock

Una volta applicato uno stile, in modo esplicito o implicito, diventa sealed e non può essere modificato. Se si desidera modificare uno stile applicato, creare un nuovo stile per sostituire quello esistente. Per altre informazioni, vedere la proprietà IsSealed.

È possibile creare un oggetto che sceglie uno stile da applicare in base alla logica personalizzata. Per un esempio, vedere l'esempio fornito per la StyleSelector classe .

Applicare uno stile a livello di codice

Per assegnare uno stile denominato a un elemento a livello di codice, ottenere lo stile dall'insieme resources e assegnarlo alla proprietà dell'elemento Style . Gli elementi in una raccolta di risorse sono di tipo Object. Pertanto, è necessario eseguire il cast dello stile recuperato a un System.Windows.Style oggetto prima di assegnarlo alla Style proprietà . Ad esempio, il codice seguente imposta lo stile di un TextBlock oggetto denominato textblock1 sullo stile TitleTextdefinito.

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

Estendere uno stile

È possibile che i due TextBlock elementi convidano alcuni valori delle proprietà, ad esempio FontFamily e il centro HorizontalAlignment. Ma vuoi anche che il testo Immagini personali abbia alcune proprietà aggiuntive. A tale scopo, è possibile creare un nuovo stile basato sul primo stile, come illustrato di seguito.

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Questo TextBlock stile è ora centrato, usa un Comic Sans MS tipo di carattere con una dimensione di 26e il colore di primo piano impostato sull'oggetto LinearGradientBrush illustrato nell'esempio. Si noti che esegue l'override del FontSize valore dello stile di base. Se sono presenti più di una Setter proprietà che punta alla stessa proprietà in un Style, l'oggetto Setter dichiarato per ultimo ha la precedenza.

Di seguito viene illustrato l'aspetto degli TextBlock elementi:

Styled TextBlocks

Questo TitleText stile estende lo stile creato per il TextBlock tipo, a cui viene fatto riferimento con BasedOn="{StaticResource {x:Type TextBlock}}". È anche possibile estendere uno stile con un x:Key oggetto utilizzando l'oggetto x:Key dello stile . Ad esempio, se è presente uno stile denominato Header1 e si vuole estendere tale stile, si userà BasedOn="{StaticResource Header1}".

Relazione tra la proprietà TargetType e l'attributo x:Key

Come illustrato in precedenza, impostando la TargetType proprietà su TextBlock senza assegnare lo stile un x:Key fa sì che lo stile venga applicato a tutti gli TextBlock elementi. In questo caso, l'attributo x:Key è impostato in modo implicito su {x:Type TextBlock}. Ciò significa che se si imposta in modo esplicito il x:Key valore su un valore diverso {x:Type TextBlock}da , non Style viene applicato automaticamente a tutti gli TextBlock elementi. È invece necessario applicare lo stile (usando il x:Key valore) agli TextBlock elementi in modo esplicito. Se lo stile si trova nella sezione resources e non si imposta la TargetType proprietà sullo stile, è necessario impostare l'attributo x:Key .

Oltre a fornire un valore predefinito per , x:Keyla TargetType proprietà specifica il tipo a cui si applicano le proprietà setter. Se non si specifica un TargetTypeoggetto , è necessario qualificare le proprietà negli Setter oggetti con un nome di classe usando la sintassi Property="ClassName.Property". Ad esempio, anziché impostare Property="FontSize", è necessario impostare su Property"TextBlock.FontSize" o "Control.FontSize".

Si noti anche che molti controlli WPF sono costituiti da una combinazione di altri controlli WPF. Se si crea uno stile che si applica a tutti i controlli di un tipo, è possibile che si ottengano risultati imprevisti. Ad esempio, se si crea uno stile destinato al TextBlock tipo in un Windowoggetto , lo stile viene applicato a tutti i TextBlock controlli della finestra, anche se fa TextBlock parte di un altro controllo, ad esempio .ListBox

Vedi anche