Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Gli stili e le modelli di Windows Presentation Foundation (WPF) fanno riferimento a una suite di funzionalità usate per creare effetti visivamente accattivanti e un aspetto coerente per il prodotto. Quando si personalizza l'aspetto di un'app, si vuole un modello di stili e modelli avanzato che consentono di mantenere e condividere l'aspetto all'interno e tra le app. WPF fornisce tale modello.
Un'altra funzionalità del modello di stile WPF è la separazione della presentazione e della logica. I progettisti possono lavorare sull'aspetto di un'app usando solo XAML contemporaneamente che gli sviluppatori lavorano sulla logica di programmazione usando C# o Visual Basic.
Questa panoramica è incentrata sugli aspetti relativi allo stile e alla creazione di modelli dell'app e non illustra i concetti di data binding. Per informazioni sul data binding, vedere Cenni preliminari sull'associazione dati.
È importante comprendere le risorse, quali sono gli stili e i modelli da riutilizzare. Per altre informazioni sulle risorse, vedere Panoramica delle risorse XAML.
Esempio
Il codice di esempio fornito in questa panoramica si basa su una semplice applicazione di esplorazione di foto illustrata nella figura seguente.
Questo semplice esempio di foto usa stili e modelli per creare un'esperienza utente visivamente accattivante. L'esempio include due TextBlock elementi e un ListBox controllo associato a un elenco di immagini.
Per l'esempio completo, vedere Introduzione a un esempio di applicazione di stili e di modelli.
Stili
È possibile considerare un Style oggetto come un modo pratico per applicare un set di valori di proprietà a 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, seguono le stesse regole di ambito di tutte le risorse. Dove dichiari uno stile influisce sulla posizione in cui puoi applicarlo. Ad esempio, se dichiari lo stile nell'elemento radice del file XAML di definizione dell'app, puoi usare lo stile ovunque nella tua app.
Il codice XAML seguente dichiara due stili per un oggetto TextBlock: uno applicato automaticamente a tutti gli TextBlock elementi e un altro a cui è necessario fare riferimento in modo esplicito.
<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>
Nell'esempio seguente viene illustrato come usare gli stili precedenti.
<StackPanel>
<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
Per altre informazioni, vedere Creare uno stile per un controllo .
ControlTemplates
In WPF, l'attributo ControlTemplate di un controllo definisce l'aspetto del controllo. È possibile modificare la struttura e l'aspetto di un controllo definendo un nuovo ControlTemplate controllo e assegnandolo a un controllo . In molti casi, i modelli offrono una flessibilità sufficiente, in modo che non sia necessario scrivere controlli personalizzati.
A ogni controllo è assegnato un modello predefinito alla proprietà Control.Template . Il modello connette la presentazione visiva del controllo con le funzionalità del controllo. Poiché definisci un modello in XAML, puoi modificare l'aspetto del controllo senza scrivere codice. Ogni modello è progettato per un controllo specifico, ad esempio .Button
Importante
Quando si modifica la struttura ad albero visuale di un controllo, è necessario sostituire l'intero ControlTemplate oggetto. Non è possibile sostituire solo parte della struttura ad albero visuale di un controllo. Per modificare la struttura ad albero visivo di un controllo, è necessario impostare la proprietà Template del controllo al suo nuovo e completo ControlTemplate.
In genere dichiari un modello come risorsa nella Resources sezione di un file XAML. Come per tutte le risorse, si applicano regole di ambito.
I modelli di controllo sono molto più complessi rispetto a uno stile. Questa complessità esiste perché il modello di controllo riscrive l'aspetto visivo dell'intero controllo, mentre uno stile applica semplicemente le modifiche delle proprietà al controllo esistente. Tuttavia, poiché il modello di un controllo viene applicato impostando la proprietà Control.Template , è possibile utilizzare uno stile per definire o impostare un modello.
Le finestre di progettazione in genere consentono di creare una copia di un modello esistente e modificarla. Ad esempio, nella finestra di progettazione WPF di Visual Studio selezionare un CheckBox controllo e quindi fare clic con il pulsante destro del mouse e scegliere Modifica modello>Crea una copia. Questo comando genera uno stile che definisce un modello.
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background1}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border1}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid">
<Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="1" Opacity="0" Stretch="None"/>
<Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="2" Opacity="0"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
... content removed to save space ...
La modifica di una copia di un modello è un ottimo modo per apprendere il funzionamento dei modelli. Anziché creare un nuovo modello vuoto, è più semplice modificare una copia e modificare alcuni aspetti della presentazione visiva.
Per un esempio, vedere Creare un modello per un controllo .
TemplateBinding
È possibile notare che la risorsa modello definita nella sezione precedente usa l'estensione di markup TemplateBinding. Un TemplateBinding è una forma ottimizzata di un'associazione per gli scenari di modello, analoga a un'associazione costruita con {Binding RelativeSource={RelativeSource TemplatedParent}}.
TemplateBinding è utile per l'associazione di parti del modello alle proprietà del controllo. Ad esempio, ogni controllo ha una BorderThickness proprietà . Utilizzare un TemplateBinding oggetto per gestire l'elemento nel modello interessato da questa impostazione di controllo.
ContentControl e ItemsControl
Se un ContentPresenter è dichiarato nel ControlTemplate di un ContentControl, l'oggetto ContentPresenter viene automaticamente associato alle proprietà ContentTemplate e Content. Analogamente, un oggetto ItemsPresenter che si trova in ControlTemplate di un oggetto ItemsControl viene associato automaticamente alle ItemTemplate proprietà e Items .
Modelli di dati
In questa app di esempio un ListBox controllo viene associato a un elenco di foto.
<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>
L'immagine ListBox è attualmente simile alla seguente.
La maggior parte dei controlli ha un tipo di contenuto e spesso il contenuto proviene dai dati a cui si esegue il binding. In questo esempio i dati sono l'elenco di foto. In WPF si usa un DataTemplate per definire la rappresentazione visiva dei dati. Fondamentalmente, ciò che si inserisce in un DataTemplate determina l'aspetto dei dati nell'app sottoposta a rendering.
In questa app di esempio ogni oggetto personalizzato Photo ha una Source proprietà di tipo stringa che specifica il percorso del file dell'immagine. In questo momento, gli oggetti foto appaiono come percorsi di file.
public class Photo
{
public Photo(string path)
{
Source = path;
}
public string Source { get; }
public override string ToString() => Source;
}
Public Class Photo
Sub New(ByVal path As String)
Source = path
End Sub
Public ReadOnly Property Source As String
Public Overrides Function ToString() As String
Return Source
End Function
End Class
Per visualizzare le foto come immagini, si crea un oggetto DataTemplate come risorsa.
<Window.Resources>
<!-- .... other resources .... -->
<!--DataTemplate to display Photos as images
instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
<Border Margin="3">
<Image Source="{Binding Source}"/>
</Border>
</DataTemplate>
</Window.Resources>
Si noti che la DataType proprietà è simile alla TargetType proprietà dell'oggetto Style. Se si aggiunge un oggetto DataTemplate alla sezione resources e si imposta la DataType proprietà su un tipo e si omette un x:Keyoggetto , DataTemplate viene applicato ogni volta che viene visualizzato tale tipo. È anche possibile assegnare un DataTemplate a un x:Key e poi impostarlo come StaticResource per le proprietà che accettano tipi DataTemplate, come la proprietà ItemTemplate o la proprietà ContentTemplate.
Fondamentalmente, nell'esempio precedente DataTemplate si definisce che ogni volta che è presente un oggetto Photo, dovrebbe essere visualizzato come un Image all'interno di un Border. Usando questo DataTemplateoggetto , l'app avrà ora un aspetto simile a questa immagine.
Il modello di templating dei dati fornisce altre funzionalità. Ad esempio, se si visualizzano dati di raccolta che contengono altre raccolte usando un tipo come HeaderedItemsControl, Menu o TreeView, usare il HierarchicalDataTemplate. Un'altra funzionalità di creazione di modelli di dati è DataTemplateSelector, che è possibile usare per scegliere un DataTemplate basato sulla logica personalizzata. Per altre informazioni, vedere Cenni preliminari sui modelli di dati, in cui vengono discusse più dettagliatamente le diverse caratteristiche dei modelli di dati.
Attivatori
Un trigger imposta proprietà o avvia azioni, ad esempio un'animazione, quando un valore di proprietà cambia o quando viene generato un evento.
Style, ControlTemplatee DataTemplate tutti hanno una Triggers proprietà che può contenere un set di trigger. Esistono diversi tipi di trigger.
Trigger di proprietà
Un Trigger oggetto che imposta i valori delle proprietà o avvia azioni in base al valore di una proprietà è denominato trigger di proprietà.
Per illustrare come usare i trigger di proprietà, è possibile rendere ogni ListBoxItem elemento parzialmente trasparente, a meno che non sia selezionato. Lo stile seguente imposta il Opacity valore di un ListBoxItem su 0.5. Quando la IsSelected proprietà è true, tuttavia, Opacity è impostata su 1.0.
<Window.Resources>
<!-- .... other resources .... -->
<Style TargetType="ListBoxItem">
<Setter Property="Opacity" Value="0.5" />
<Setter Property="MaxHeight" Value="75" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Opacity" Value="1.0" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Questo esempio usa un Trigger oggetto per impostare un valore di proprietà, ma si noti che la Trigger classe ha anche le EnterActions proprietà e ExitActions che consentono a un trigger di eseguire azioni.
Si noti che la MaxHeight proprietà di ListBoxItem è impostata su 75. Nella figura seguente, il terzo elemento è l'elemento selezionato.
Trigger di eventi e storyboard
Un altro tipo di trigger è EventTrigger, che avvia un set di azioni in base all'occorrenza di un evento. Ad esempio, gli oggetti seguenti EventTrigger specificano che quando il puntatore del mouse entra in ListBoxItem, la proprietà MaxHeight viene animata fino a un valore di 90 in un periodo di 0.2 secondi. Quando il puntatore del mouse si allontana dall'elemento, la proprietà torna al valore originale in un periodo di 1 secondo. Si noti come non è necessario specificare un To valore per l'animazione MouseLeave . Questo comportamento si verifica perché l'animazione tiene traccia del valore originale.
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Opacity" Value="1.0" />
</Trigger.Setters>
</Trigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:0.2"
Storyboard.TargetProperty="MaxHeight"
To="90" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:1"
Storyboard.TargetProperty="MaxHeight" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
Per altre informazioni, vedere la panoramica degli storyboard.
Nella figura seguente il mouse punta al terzo elemento.
MultiTrigger, DataTrigger e MultiDataTrigger
Oltre a Trigger e EventTrigger, esistono altri tipi di trigger. Usando MultiTrigger, è possibile impostare i valori delle proprietà in base a più condizioni. Usare DataTrigger e MultiDataTrigger quando la proprietà della condizione è associata a dati.
Stati di visualizzazione
I controlli sono sempre in uno stato specifico. Ad esempio, quando il mouse si sposta sulla superficie di un controllo, il controllo si trova nello stato MouseOvercomune . Un controllo senza uno stato specifico è nello stato comune Normal . Gli stati sono suddivisi in gruppi e gli stati indicati in precedenza fanno parte del gruppo CommonStatesdi stati . La maggior parte dei controlli ha due gruppi di stato: CommonStates e FocusStates. Di ogni gruppo di stato applicato a un controllo, un controllo è sempre in uno stato di ogni gruppo, ad esempio CommonStates.MouseOver e FocusStates.Unfocused. Tuttavia, un controllo non può trovarsi in due stati diversi all'interno dello stesso gruppo, ad esempio CommonStates.Normal e CommonStates.Disabled. La tabella seguente mostra gli stati che la maggior parte dei controlli riconosce e usa.
| VisualState Nome | Nome del VisualStateGroup | Descrizione |
|---|---|---|
Normal |
CommonStates |
Stato predefinito. |
MouseOver |
CommonStates |
Il puntatore del mouse è posizionato sopra l'elemento di controllo. |
Pressed |
CommonStates |
Il pulsante viene premuto. |
Disabled |
CommonStates |
Il controllo è disabilitato. |
Focused |
FocusStates |
Il controllo è in focus. |
Unfocused |
FocusStates |
Il controllo non ha lo stato attivo. |
Definendo un oggetto System.Windows.VisualStateManager sull'elemento radice di un modello di controllo, puoi attivare animazioni quando un controllo entra in uno stato specifico.
VisualStateManager Dichiara le combinazioni di VisualStateGroup e VisualState da controllare. Quando il controllo entra in uno stato monitorato, l'animazione definita dall'oggetto VisualStateManager viene avviata.
Ad esempio, il codice XAML seguente controlla lo CommonStates.MouseOver stato per animare il colore di riempimento dell'elemento denominato backgroundElement. Quando il controllo torna allo CommonStates.Normal stato, l'animazione ripristina il colore di riempimento dell'elemento denominato backgroundElement.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{TemplateBinding Background}"
Duration="0:0:0.3"/>
</VisualState>
<VisualState Name="MouseOver">
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow"
Duration="0:0:0.3"/>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
Per ulteriori informazioni sugli storyboard, vedere Panoramica di Storyboards.
Risorse condivise e temi
Un'app WPF tipica potrebbe avere più risorse dell'interfaccia utente applicate in tutta l'app. Puoi considerare questo set di risorse il tema per l'app. WPF supporta la creazione di pacchetti di risorse dell'interfaccia utente come tema usando un dizionario risorse incapsulato dalla ResourceDictionary classe.
Definire i temi WPF usando il meccanismo di applicazione di stili e modelli esposto da WPF per personalizzare gli oggetti visivi di qualsiasi elemento.
Archiviare le risorse del tema WPF nei dizionari risorse incorporati. È necessario incorporare questi dizionari di risorse all'interno di un assembly firmato. È possibile incorporarli nello stesso assembly del codice stesso o in un assembly affiancato. Per PresentationFramework.dll, l'assembly che contiene controlli WPF, gli sviluppatori incorporano risorse del tema in una serie di assembly affiancati. Il sistema operativo determina il dizionario risorse del tema da usare in fase di esecuzione.
Il tema è l'ultimo posto da cercare quando si cerca lo stile di un elemento. In genere, la ricerca inizia camminando sull'albero degli elementi cercando una risorsa appropriata, quindi cerca nella raccolta di risorse dell'app e infine esegue una query sul sistema. Questo modello di ricerca offre agli sviluppatori di app la possibilità di ridefinire lo stile per qualsiasi oggetto a livello di albero o app prima di raggiungere il tema.
È possibile definire dizionari risorse come singoli file che consentono di riutilizzare un tema in più app. È inoltre possibile creare temi scambiabili definendo più dizionari risorse che forniscono gli stessi tipi di risorse ma con valori diversi. La ridefinizione di questi stili o altre risorse a livello di app è l'approccio consigliato per l'interfaccia di un'app.
Per condividere un set di risorse, inclusi gli stili e i modelli, tra le app, creare un file XAML e definire un ResourceDictionary oggetto che include un riferimento a un shared.xaml file.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>
Condividendo shared.xaml, che a sua volta definisce un ResourceDictionary contenente un set di risorse di stile e pennello, è possibile ottenere un aspetto coerente per i controlli in un'app.
Per altre informazioni, vedere Dizionari risorse uniti.
Per creare un tema per il controllo personalizzato, vedere la sezione Definizione delle risorse a livello di tema della panoramica sulla creazione di controlli.
Uso dei temi predefiniti
WPF include diversi temi predefiniti che è possibile applicare in modo esplicito all'applicazione. Questi temi sono incorporati negli assembly PresentationFramework ed è possibile farvi riferimento usando gli URI di tipo pack nei dizionari risorse dell'applicazione.
Per applicare un tema predefinito, integrare il dizionario delle risorse del tema nelle risorse dell'applicazione nel seguente modo App.xaml:
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PresentationFramework.Aero2;component/themes/Aero2.NormalColor.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Temi predefiniti disponibili
La tabella seguente elenca i temi predefiniti disponibili tramite gli URI pack:
| Tema | Pack URI | Descrizione |
|---|---|---|
| Aero2 | /PresentationFramework.Aero2;component/themes/Aero2.NormalColor.xaml |
Tema predefinito per le applicazioni windows 8 e successive. |
| AeroLite | /PresentationFramework.AeroLite;component/themes/AeroLite.NormalColor.xaml |
Versione semplificata di Aero2 con effetti visivi ridotti. |
| Aero | /PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml |
Tema di Windows 7 con effetti di vetro e sfumature. |
| Fluent | /PresentationFramework.Fluent;component/Themes/Fluent.xaml |
Tema in stile Windows 11 con supporto per la modalità chiara/scura (.NET 9+). |
| Luna (Blu) | /PresentationFramework.Luna;component/themes/Luna.NormalColor.xaml |
Combinazione di colori blu predefinita di Windows XP. |
| Luna (Argento) | /PresentationFramework.Luna;component/themes/Luna.Metallic.xaml |
Schema di colori argento metallico di Windows XP. |
| Luna (Oliva) | /PresentationFramework.Luna;component/themes/Luna.Homestead.xaml |
Combinazione di colori di Windows XP verde oliva. |
| Royale | /PresentationFramework.Royale;component/themes/Royale.NormalColor.xaml |
Tema di Windows XP Media Center Edition. |
| Classico | /PresentationFramework.Classic;component/themes/Classic.xaml |
Aspetto tradizionale di Windows 95/98/2000. |
Annotazioni
Per le applicazioni .NET Framework, potrebbe essere necessario aggiungere riferimenti agli assembly del tema (ad esempio PresentationFramework.Aero2) nel progetto. Per le applicazioni .NET, gli assembly del tema vengono in genere inclusi automaticamente.
Suggerimento
Per informazioni di riferimento per gli sviluppatori, Visual Studio include file XAML per questi temi nella directory di installazione, in genere disponibile in C:\Programmi\Microsoft Visual Studio\2022\<edition>\DesignTools\SystemThemes\wpf. Questi file sono utili per comprendere la struttura del tema, ma non vengono usati in fase di esecuzione.
Uso del tema Fluent moderno (.NET 9+)
Per .NET 9 e versioni successive, è possibile usare il nuovo tema Fluent che supporta le modalità chiaro e scuro:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
In alternativa, è possibile usare la ThemeMode proprietà per un'applicazione tema ancora più semplice:
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ThemeMode="System">
</Application>
Vedere anche
.NET Desktop feedback