Condividi tramite


Stili XAML

Puoi personalizzare l'aspetto delle tue app in molti modi usando il framework XAML. Gli stili consentono di impostare le proprietà del controllo e riutilizzare tali impostazioni per un aspetto coerente in più controlli.

WinUI e stili

A partire da WinUI 2.2, abbiamo usato WinUI per distribuire nuovi aggiornamenti dello stile di visualizzazione nei componenti dell'interfaccia utente. Se si nota che l'interfaccia utente non viene aggiornata agli stili più recenti, assicurarsi di eseguire l'aggiornamento al pacchetto NuGet WinUI più recente.

A partire da WinUI 2.6, forniamo nuovi stili per la maggior parte dei controlli e un nuovo sistema di controllo delle versioni che consente di ripristinare gli stili di controllo precedenti, se necessario. Ti invitiamo a usare i nuovi stili, in quanto meglio corrispondono alla direzione di progettazione di Windows. Tuttavia, se lo scenario non può supportare i nuovi stili, le versioni precedenti sono ancora disponibili.

È possibile modificare la versione dello stile impostando proprietà di ControlsResourcesVersion nell'oggetto XamlControlsResources che includi nel tuo Application.Resources quando utilizzi la versione 2 di WinUI. ControlsResourcesVersion predefinisce al valore di enumerazione Version2.

L'impostazione di questo valore su Version1 determina XamlControlsResources il caricamento delle versioni di stile precedenti anziché dei nuovi stili usati dalla versione più recente di WinUI. La modifica di questa proprietà in fase di esecuzione non è supportata e la funzionalità di ricaricamento rapido di VisualStudio non funzionerà; Tuttavia, dopo aver ricompilato l'applicazione, gli stili del controllo cambiano.

<Application.Resources>
    <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" 
                           ControlsResourcesVersion="Version1"/>
</Application.Resources>

Nozioni di base sullo stile

Usare gli stili per estrarre le impostazioni delle proprietà visive in risorse riutilizzabili. Ecco un esempio che mostra 3 pulsanti con uno stile che imposta le proprietà di BorderBrush , BorderThickness e Foreground . Applicando uno stile, è possibile rendere i controlli uguali senza dover impostare queste proprietà in ogni controllo separatamente.

Screenshot di tre pulsanti stilizzati disposti affiancati.

Puoi definire uno stile inline nel codice XAML per un controllo o come risorsa riutilizzabile. Definire le risorse nel file XAML di una singola pagina, nel file App.xaml o in un file XAML separato del dizionario risorse. Un file XAML del dizionario delle risorse può essere condiviso tra app e più dizionari delle risorse possono essere uniti in una singola app. Dove la risorsa è definita determina l'ambito in cui può essere usato. Le risorse a livello di pagina sono disponibili solo nella pagina in cui sono definite. Se le risorse con la stessa chiave sono definite sia in App.xaml che in una pagina, la risorsa nella pagina esegue l'override della risorsa in App.xaml. Se una risorsa è definita in un file di dizionario risorse separato, l'ambito viene determinato da dove viene fatto riferimento al dizionario risorse.

Nella definizione Style è necessario un attributo TargetType e una raccolta di uno o più elementi Setter. L'attributo TargetType è una stringa che specifica un tipo FrameworkElement a cui applicare lo stile. Il valore TargetType deve specificare un tipo derivato da FrameworkElementdefinito da Windows Runtime o un tipo personalizzato disponibile in un assembly a cui si fa riferimento. Se si tenta di applicare uno stile a un controllo e il tipo del controllo non corrisponde all'attributo TargetType dello stile che si sta tentando di applicare, si verifica un'eccezione.

Ogni elemento Setter richiede un Property e un Value. Queste impostazioni delle proprietà indicano la proprietà del controllo a cui si applica l'impostazione e il valore da impostare per tale proprietà. È possibile impostare il Setter.Value con la sintassi dell'attributo o dell'elemento proprietà. Il codice XAML mostra lo stile applicato ai pulsanti mostrati in precedenza. In questo codice XAML, i primi due elementi Setter usano la sintassi degli attributi, ma l'ultimo Setter, per la proprietà BorderBrush , usa la sintassi degli elementi proprietà. L'esempio non usa l'attributo x:Key, quindi lo stile viene applicato in modo implicito ai pulsanti. L'applicazione di stili in modo implicito o esplicito viene illustrata nella sezione successiva.

<Page.Resources>
    <Style TargetType="Button">
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="BorderBrush" >
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<StackPanel Orientation="Horizontal">
    <Button Content="Button"/>
    <Button Content="Button"/>
    <Button Content="Button"/>
</StackPanel>

Applicare uno stile implicito o esplicito

Se si definisce uno stile come risorsa, è possibile applicarlo ai controlli in due modi:

  • In modo implicito, specificando solo il TargetType per il Style.
  • In modo esplicito, specificando un TargetType e un attributo x:Key per lo Style e quindi impostando la proprietà Style del controllo di destinazione con un riferimento all'estensione di markup {StaticResource} che utilizza la chiave esplicita.

Se uno stile contiene l'attributo x:Key, è possibile applicarlo solo a un controllo impostando la proprietà Style del controllo sullo stile con chiave. Al contrario, uno stile senza un attributo x:Key viene applicato automaticamente a ogni controllo del tipo di destinazione, che non ha altrimenti un'impostazione di stile esplicita.

Ecco due pulsanti che illustrano stili impliciti ed espliciti.

pulsanti stilizzati in modo implicito ed esplicito.

In questo esempio il primo stile ha un attributo x:Key e il tipo di destinazione è Button. La proprietà Style del primo pulsante è impostata su questa chiave, quindi questo stile viene applicato esplicitamente. Il secondo stile viene applicato in modo implicito al secondo pulsante perché il tipo di destinazione è Pulsante e lo stile non ha un attributo x:Key.

<Page.Resources>
    <Style x:Key="PurpleStyle" TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Foreground" Value="Purple"/>
    </Style>

    <Style TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform Angle="25"/>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Green"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Foreground" Value="Green"/>
    </Style>
</Page.Resources>

<Grid x:Name="LayoutRoot">
    <Button Content="Button" Style="{StaticResource PurpleStyle}"/>
    <Button Content="Button"/>
</Grid>

Utilizzare stili basati su

Per semplificare la manutenzione degli stili e ottimizzare il riutilizzo dello stile, è possibile creare stili che ereditano da altri stili. Per creare stili ereditati, si utilizza la proprietà BasedOn. Gli stili che ereditano da altri stili devono essere destinati allo stesso tipo di controllo o a un controllo derivato dal tipo a cui è destinato lo stile di base. Ad esempio, se uno stile di base si rivolge a ContentControl, gli stili basati su questo stile possono rivolgersi a ContentControl o a tipi che derivano da ContentControl, come Button e ScrollViewer. Se un valore non è impostato nel modello su cui si basa, viene ereditato dallo stile di base. Per modificare un valore derivato dallo stile di base, lo stile derivato sovrascrive quel valore. L'esempio seguente mostra un Button e un CheckBox con stili che ereditano dallo stesso stile di base.

pulsanti stilizzati usando stili basati su.

Lo stile di base punta a ContentControl, e imposta le proprietà Heighte Width. Gli stili basati su questo stile hanno come destinatari CheckBox e Button, derivati da ContentControl. Gli stili basati su impostano colori diversi per le proprietà BorderBrush e Foreground. In genere non si inserisce un bordo intorno a un CheckBox. Lo facciamo qui per evidenziare gli effetti dello stile.

<Page.Resources>
    <Style x:Key="BasicStyle" TargetType="ContentControl">
        <Setter Property="Width" Value="130" />
        <Setter Property="Height" Value="30" />
    </Style>

    <Style x:Key="ButtonStyle" TargetType="Button"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Orange" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Red" />
    </Style>

    <Style x:Key="CheckBoxStyle" TargetType="CheckBox"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Green" />
    </Style>
</Page.Resources>

<StackPanel>
    <Button Content="Button" Style="{StaticResource ButtonStyle}" Margin="0,10"/>
    <CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle}"/>
</StackPanel>

Usare gli strumenti per lavorare facilmente con gli stili

Un modo rapido per applicare stili ai controlli consiste nel fare clic con il pulsante destro del mouse su un controllo nell'area di progettazione XAML di Microsoft Visual Studio e scegliere Modifica stile o Modifica modello (a seconda del controllo su cui si fa clic con il pulsante destro del mouse). È quindi possibile applicare uno stile esistente selezionando Applica risorsa o definire un nuovo stile selezionando Crea vuoto. Se crei uno stile vuoto, hai la possibilità di definirlo nella pagina, nel file App.xaml o in un dizionario risorse separato.

Stile di design leggero

L'override dei pennelli di sistema viene in genere eseguita a livello di app o di pagina e in entrambi i casi l'override del colore influirà su tutti i controlli che fanno riferimento a tale pennello e in XAML molti controlli possono fare riferimento allo stesso pennello di sistema.

Screenshot di due pulsanti: uno nello stato di riposo e uno con stile leggero applicato.

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                 <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                 <SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
                 <SolidColorBrush x:Key="ButtonBorderBrush" Color="MediumSlateBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Page.Resources>

Per gli stati come PointerOver (il mouse viene posizionato sul pulsante), PuntatorePremuto (il pulsante è stato premuto) o Disabilitato (il pulsante non è interattivo). Queste terminazioni vengono aggiunte ai nomi di stile Lightweight originali: ButtonBackgroundPointerOver, ButtonForegroundPressed, ButtonBorderBrushDisablede così via. Modificando anche questi pennelli, si assicurerà che i controlli siano colorati in modo coerente con il tema dell'app.

L'inserimento di questi override del pennello al livello di App.Resources modificherà tutti i pulsanti all'interno dell'intera app, anziché in una singola pagina.

Stili per controllo

In altri casi, è consigliabile modificare un singolo controllo in una sola pagina per avere un aspetto specifico, senza modificare altre versioni di tale controllo:

Screenshot di tre pulsanti stilizzati disposti uno sopra l'altro.

<CheckBox Content="Normal CheckBox" Margin="5"/>
<CheckBox Content="Special CheckBox" Margin="5">
    <CheckBox.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="CheckBoxForegroundUnchecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxForegroundChecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckGlyphForegroundChecked"
                        Color="White"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundStrokeChecked"  
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundFillChecked"
                        Color="Purple"/>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </CheckBox.Resources>
</CheckBox>
<CheckBox Content="Normal CheckBox" Margin="5"/>

Ciò influenzerebbe solo la "Casella di controllo speciale" sulla pagina in cui è presente il controllo.

Controlli personalizzati

Quando si creano controlli personalizzati che possono essere visivamente e/o allineati a livello funzionale con i controlli predefiniti, è consigliabile usare stili impliciti e risorse di stili leggeri per definire il contenuto personalizzato. È possibile usare direttamente le risorse oppure creare un nuovo alias per la risorsa.

Uso diretto delle risorse di controllo

Ad esempio, se stai scrivendo un controllo simile a un pulsante, puoi fare riferimento direttamente alle risorse del pulsante come segue:

<Style TargetType="local:MyCustomControl">
  <Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
  <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
</Style>

Rinomina delle risorse di controllo con alias nuovi

In alternativa, se si preferisce creare risorse personalizzate, è consigliabile associare tali nomi personalizzati alle nostre risorse di stile Lightweight predefinite.

Ad esempio, lo stile del controllo personalizzato potrebbe avere definizioni di risorse speciali:

<Style TargetType="local:MyCustomControl">
  <Setter Property="Background" Value="{ThemeResource MyCustomControlBackground}" />
  <Setter Property="BorderBrush" Value="{ThemeResource MyCustomControlBorderBrush}"/>
</Style>

Nel dizionario risorse o nella definizione principale è necessario associare le risorse di stile Lightweight a quelle personalizzate:

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>        
    <ResourceDictionary x:Key="Light">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>
    <ResourceDictionary x:Key="HighContrast">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

È necessario usare un ThemeDictionary oggetto duplicato tre volte per gestire correttamente le tre diverse modifiche del tema (Default, Light, HighContrast).

Attenzione

Se assegni una risorsa di stile Lightweight a un nuovo alias e ridefinisci anche la risorsa di stile Lightweight, è possibile che la personalizzazione non venga applicata se la ricerca della risorsa non è nell'ordine corretto. Ad esempio, se si esegue l'override di ButtonBackground in un punto in cui viene eseguita la ricerca prima che MyCustomControlBackground venga trovata, l'override potrebbe essere ignorato.

Evitare controlli di rimodulazione

WinUI 2.2 o versione successiva include nuovi stili e modelli per i controlli winUI e di sistema.

Il modo migliore per rimanere aggiornati con gli stili di visualizzazione più recenti consiste nell'usare il pacchetto WinUI 2 più recente ed evitare stili e modelli personalizzati (noti anche come ri-templating). Gli stili sono ancora un modo pratico per applicare un set di valori in modo coerente tra i controlli nella tua app. Assicurati di basarti sui nostri ultimi stili.

Per i controlli di sistema che usano gli stili WinUI (Windows.UI.Xaml.Controls spazio dei nomi), impostare BasedOn="{StaticResource Default<ControlName>Style}", dove <ControlName> è il nome del controllo. Per esempio:

<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
    <Setter Property="Foreground" Value="Blue"/>
</Style>

Per i controlli WinUI 2 (Microsoft.UI.Xaml.Controls spazio dei nomi), lo stile predefinito è definito nei metadati, quindi omettere BasedOn.

Controlli derivati

Se si deriva un controllo personalizzato da un controllo XAML esistente, non otterrà gli stili WinUI 2 per impostazione predefinita. Per applicare gli stili WinUI 2:

  • Creare un nuovo Style con il TargetType impostato sul controllo personalizzato.
  • Basare lo stile sullo stile predefinito del controllo da cui è derivato.

Uno scenario comune per questo è derivare un nuovo controllo da ContentDialog. In questo esempio viene illustrato come creare un nuovo stile che si applica DefaultContentDialogStyle alla finestra di dialogo personalizzata.

<ContentDialog
    x:Class="ExampleApp.SignInContentDialog"
    ... >

    <ContentDialog.Resources>
        <Style TargetType="local:SignInContentDialog" BasedOn="{StaticResource DefaultContentDialogStyle}"/>
        ...
    </ContentDialog.Resources> 
    <!-- CONTENT -->
</ContentDialog>        

Proprietà del modello

Un setter di stile può essere usato per la proprietà template di un controllo e questo costituisce la maggior parte di uno stile XAML tipico e delle risorse XAML di un'app. Questo argomento viene illustrato in modo più dettagliato nell'argomento Modelli di controllo.