Co jsou styly a šablony?

Styling a šablonování Windows Presentation Foundation (WPF) odkazují na sadu funkcí, které používáte k vytváření vizuálně atraktivních efektů a konzistentního vzhledu produktu. Když přizpůsobíte vzhled aplikace, budete chtít silný styl a šablonovací model, který vám umožní udržovat a sdílet vzhled v aplikacích i mezi aplikacemi. WPF poskytuje tento model.

Další funkcí modelu stylů WPF je oddělení prezentace a logiky. Návrháři můžou pracovat na vzhledu aplikace jenom pomocí XAML současně, kdy vývojáři pracují na programovací logice pomocí jazyka C# nebo Visual Basic.

Tento přehled se zaměřuje na styly a šablonování aspektů aplikace a neprobírá žádné koncepty datových vazeb. Informace o datové vazbě naleznete v tématu Přehled datových vazeb.

Je důležité pochopit prostředky, které umožňují opakované použití stylů a šablon. Další informace o prostředcích najdete v tématu Přehled prostředků XAML.

Ukázka

Ukázkový kód uvedený v tomto přehledu vychází z jednoduché aplikace pro procházení fotek znázorněné na následujícím obrázku.

Styled ListView

Tato jednoduchá ukázka fotek používá styly a šablony k vytvoření vizuálně atraktivního uživatelského prostředí. Ukázka má dva TextBlock prvky a ovládací prvek ListBox, který je svázán se seznamem obrázků.

Kompletní ukázku najdete v tématu Úvod k ukázce stylů a šablon.

Styly

Style si můžete představit jako pohodlný způsob použití sady hodnot vlastností na více prvků. Styl můžete použít u libovolného prvku odvozeného z FrameworkElement nebo FrameworkContentElement, například Window nebo Button.

Nejběžnější způsob, jak deklarovat styl, je jako prostředek v oddílu Resources v souboru XAML. Vzhledem k tomu, že styly jsou zdroje, dodržují stejná pravidla určení rozsahu jako všechny prostředky. Když deklarujete styl, bude mít vliv na to, kde ho můžete použít. Pokud například deklarujete styl v kořenovém prvku souboru XAML definice aplikace, můžete použít styl kdekoli v aplikaci.

Následující kód XAML deklaruje dva styly pro : TextBlockjeden se automaticky použije pro všechny TextBlock prvky a druhý, na který se musí explicitně odkazovat.

<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>

Následující příklad ukazuje, jak použít předchozí styly.

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

Stylované bloky textu

Další informace naleznete v tématu Vytvoření stylu ovládacího prvku.

ControlTemplates

Ve WPF definuje ControlTemplate ovládacího prvku vzhled ovládacího prvku. Strukturu a vzhled ovládacího prvku můžete změnit definováním nového ControlTemplate a jeho přiřazením k ovládacímu prvku. V mnoha případech vám šablony poskytují dostatečnou flexibilitu, abyste nemuseli psát vlastní ovládací prvky.

Každý ovládací prvek má k vlastnosti Control.Template přiřazenou výchozí šablonu. Šablona spojuje vizuální prezentaci ovládacího prvku s možnostmi ovládacího prvku. Vzhledem k tomu, že definujete šablonu v XAML, můžete změnit vzhled ovládacího prvku bez psaní kódu. Každá šablona je určena pro určitý ovládací prvek, například Button.

Důležité

Když změníte vizuální strom ovládacího prvku, musíte nahradit celý ControlTemplate. Neexistuje způsob, jak nahradit pouze část vizuálního stromu ovládacího prvku. Chcete-li změnit vizuální strom ovládacího prvku, musíte nastavit Template vlastnost ovládacího prvku na jeho nový a dokončený ControlTemplate.

Obvykle deklarujete šablonu jako prostředek v Resources části souboru XAML. Stejně jako u všech zdrojů platí pravidla pro rozsah.

Šablony ovládacích prvků jsou mnohem složitější než styl. Tato složitost existuje, protože šablona ovládacího prvku přepíše vzhled celého ovládacího prvku, zatímco styl jednoduše použije změny vlastností na existující ovládací prvek. Vzhledem k tomu, že se šablona ovládacího prvku použije nastavením vlastnosti Control.Template, můžete k definování nebo nastavení šablony použít styl.

Návrháři obecně umožňují vytvořit kopii existující šablony a upravit ji. Například v návrháři WPF sady Visual Studio vyberte ovládací prvek CheckBox a potom klikněte pravým tlačítkem myši a vyberte Upravit šablonu>Vytvořit kopii. Tento příkaz vygeneruje styl , který definuje šablonu.

<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 ...

Úprava kopie šablony je skvělý způsob, jak se naučit, jak šablony fungují. Místo vytvoření nové prázdné šablony je jednodušší upravit kopii a změnit několik aspektů vizuální prezentace.

Příklad najdete v Vytvoření šablony pro ovládací.

TemplateBinding

Možná si všimnete, že prostředek šablony definovaný v předchozí části používá rozšíření TemplateBinding Markup Extension. TemplateBinding je optimalizovaná forma vazby pro scénáře šablony, podobně jako vazby vytvořené pomocí {Binding RelativeSource={RelativeSource TemplatedParent}}. TemplateBinding je užitečné pro vazby částí šablony s vlastnostmi ovládacího prvku. Každý ovládací prvek má například vlastnost BorderThickness. Pomocí TemplateBinding můžete spravovat, na který prvek v šabloně má toto nastavení ovládacího prvku vliv.

ContentControl a ItemsControl

Je-li ContentPresenter deklarován v ControlTemplate objektu ContentControl, ContentPresenter se automaticky naváže na vlastnosti ContentTemplate a Content. Podobně se ItemsPresenter, který je v ControlTemplateItemsControl, automaticky váže na vlastnosti ItemTemplate a Items.

Šablony dat

V této ukázkové aplikaci se ovládací prvek ListBox váže na seznam fotografií.

<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
         Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>

Tento ListBox obrázek teď vypadá jako na následujícím obrázku.

ListBox před použitím šablony

Většina ovládacích prvků má určitý typ obsahu a tento obsah často pochází z dat, se kterými se svážete. V této ukázce jsou data seznamem fotek. Ve WPF použijete DataTemplate k definování vizuální reprezentace dat. V podstatě to, co vložíte do DataTemplate určuje, jak vypadají data v vykreslené aplikaci.

V této ukázkové aplikaci má každý vlastní objekt Photo vlastnost Source typu řetězec, která určuje cestu k souboru obrázku. V současné době se objekty fotografií zobrazují jako cesty k souborům.

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

Aby se fotografie zobrazovaly jako obrázky, vytvoříte DataTemplate jako zdroj.

<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>

Všimněte si, že vlastnost DataType je podobná vlastnosti TargetTypeStyle. Pokud přidáte DataTemplate do oddílu prostředků a vlastnost nastavíte DataType na typ a vynecháte x:Key, použije se DataTemplate při každém zobrazení daného typu. Můžete také přiřadit DataTemplate jako x:Key a potom ji nastavit jako StaticResource pro vlastnosti, které přijímají typy DataTemplate, jako například vlastnost ItemTemplate nebo ContentTemplate.

V podstatě DataTemplate v předcházejícím příkladu definuje, že kdykoli existuje Photo objekt, měl by se objevit jako Image uvnitř Border. Pomocí tohoto obrázku DataTemplateteď aplikace vypadá podobně jako tento obrázek.

Obrázek fotky

Model šablon dat poskytuje další funkce. Pokud například zobrazujete data kolekce, která obsahují jiné kolekce pomocí typu HeaderedItemsControl, jako je Menu nebo TreeView, použijte HierarchicalDataTemplate. Další funkcí šablonování dat je DataTemplateSelector, kterou můžete použít k výběru DataTemplate na základě vlastní logiky. Další informace najdete v tématu Přehled šablon dat, který poskytuje podrobnější diskuzi o různých funkcích šablon dat.

Spouštěče

Trigger nastaví vlastnosti nebo spustí akce, jako je animace, když se změní hodnota vlastnosti nebo při vyvolání události. Style, ControlTemplatea DataTemplate všechny mají vlastnost Triggers, která může obsahovat sadu triggerů. Existuje několik typů triggerů.

Spouštěče vlastností

Trigger, která nastavuje hodnoty vlastností nebo spouští akce na základě hodnoty vlastnosti, se nazývá aktivační událost vlastnosti.

Abyste ukázali, jak používat triggery vlastností, můžete každou ListBoxItem udělat částečně průhlednou, pokud není vybraná. Následující styl nastaví hodnotu Opacity u ListBoxItem na 0.5. Pokud je vlastnost IsSelectedtrue, je však Opacity nastavena na 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>

Tento příklad používá Trigger k nastavení hodnoty vlastnosti, ale všimněte si, že třída Trigger má také EnterActions a ExitActions vlastnosti, které umožňují triggeru provádět akce.

Všimněte si, že vlastnost MaxHeight objektu ListBoxItem je nastavena na 75. Na následujícím obrázku je třetí položka vybranou položkou.

Styled ListView

Spouštěče událostí a časové osy

Dalším typem triggeru je EventTrigger, který spouští sadu akcí na základě výskytu události. Například následující EventTrigger objekty určují, že když ukazatel myši vstoupí do ListBoxItem, vlastnost MaxHeight se mění na hodnotu 90 během období 0.2 sekund. Když se myš přesune od položky, vrátí se vlastnost k původní hodnotě za období 1 sekundu. Všimněte si, že nemusíte zadávat hodnotu To pro animaci MouseLeave. K tomuto chování dochází, protože animace sleduje původní hodnotu.

<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>

Další informace najdete v přehledu scénářů .

Na následujícím obrázku myš ukazuje na třetí položku.

Snímek obrazovky s ukázkou stylů

MultiSpouštěče, DataSpouštěče a MultiDataSpouštěče

Kromě Trigger a EventTriggerexistují i další typy triggerů. Pomocí funkce MultiTriggermůžete nastavit hodnoty vlastností na základě více podmínek. Použijte DataTrigger a MultiDataTrigger kdy je vlastnost podmínky svázaná s daty.

Vizuální stavy

Ovládací prvky jsou vždy ve stavu . Například když se myš pohybuje nad povrchem ovládacího prvku, ovládací prvek je ve společném stavu MouseOver. Ovládací prvek bez konkrétního stavu je ve společném Normal stavu. Státy jsou rozděleny do skupin a dříve uvedené státy jsou součástí skupiny států CommonStates. Většina ovládacích prvků má dvě skupiny stavů: CommonStates a FocusStates. Z každé skupiny stavů použité na ovládací prvek je ovládací prvek vždy v jednom stavu každé skupiny, například CommonStates.MouseOver a FocusStates.Unfocused. Ovládací prvek však nemůže být ve dvou různých stavech ve stejné skupině, například CommonStates.Normal a CommonStates.Disabled. Následující tabulka ukazuje stavy, které většina ovládacích prvků rozpoznává a používá.

VisualState - Název Název skupiny VisualStateGroup Popis
Normal CommonStates Výchozí stav.
MouseOver CommonStates Ukazatel myši se umístí nad ovládací prvek.
Pressed CommonStates Ovládací prvek se stiskne.
Disabled CommonStates Ovládací prvek je zakázaný.
Focused FocusStates Ovládací prvek má fokus.
Unfocused FocusStates Ovládací prvek nemá fokus.

Definováním System.Windows.VisualStateManager na kořenovém prvku šablony ovládacího prvku můžete aktivovat animace, když ovládací prvek přejde do určitého stavu. VisualStateManager deklaruje, které kombinace VisualStateGroup a VisualState je třeba sledovat. Když ovládací prvek přejde do sledovaného stavu, začíná animace definovaná VisualStateManager.

Například následující kód XAML sleduje stav CommonStates.MouseOver a animuje barvu výplně prvku s názvem backgroundElement. Když se ovládací prvek vrátí do CommonStates.Normal stavu, animace obnoví barvu výplně prvku s názvem 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>

        ...

Další informace o scénářích najdete v tématu Přehled scénářů.

Sdílené prostředky a motivy

Typická aplikace WPF může mít více prostředků uživatelského rozhraní, které použijete v celé aplikaci. Tuto sadu prostředků můžete považovat za téma aplikace. WPF podporuje balení prostředků uživatelského rozhraní jako téma pomocí slovníku prostředků, který třída ResourceDictionary zapouzdřuje.

Definujte motivy WPF pomocí mechanismu stylů a šablon, který WPF zveřejňuje pro přizpůsobení vizuálů libovolného prvku.

Ukládejte motivy WPF ve slovnících prostředků integrovaných jako zdroje. Musíte vložit tyto slovníky prostředků do podepsaného sestavení. Můžete je vložit do stejného sestavení jako samotný kód nebo do souběžného sestavení. Pro PresentationFramework.dll, sestavení, které obsahuje ovládací prvky WPF, vývojáři začleňují motivové prostředky do řady vedlejších sestavení. Operační systém určuje, který slovník prostředků motivu se má použít za běhu.

Motiv je posledním místem, kde hledat styl prvku. Hledání obvykle začíná procházením stromu prvků hledáním vhodného prostředku, poté vyhledá v kolekci prostředků aplikace a nakonec se dotáže systému. Tento vzor hledání umožňuje vývojářům aplikací před dosažením motivu předefinovat styl libovolného objektu na úrovni stromu nebo aplikace.

Slovníky zdrojů můžete definovat jako jednotlivé soubory, které vám umožní opakovaně použít rozhraní napříč více aplikacemi. Můžete také vytvořit přepínatelné motivy definováním více slovníků prostředků, které poskytují stejné typy prostředků, ale s různými hodnotami. Předefinování těchto stylů nebo jiných prostředků na úrovni aplikace je doporučeným přístupem pro úpravu aplikace.

Pokud chcete sdílet sadu prostředků, včetně stylů a šablon, napříč aplikacemi, vytvořte soubor XAML a definujte ResourceDictionary soubor, který obsahuje odkaz na shared.xaml soubor.

<ResourceDictionary.MergedDictionaries>
  <ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>

Sdílením shared.xaml, který sám definuje ResourceDictionary, který obsahuje sadu stylů a prostředků štětců, umožníte, aby ovládací prvky v aplikaci měly konzistentní vzhled.

Další informace najdete v tématu sloučené slovníky zdrojů.

Pokud chcete vytvořit motiv pro vlastní ovládací prvek, přečtěte si část Definování prostředků na úrovni motivuv přehledu vytváření ovládacích prvků.

Použití předdefinovaných motivů

WPF obsahuje několik předdefinovaných motivů, které můžete explicitně použít pro vaši aplikaci. Tyto motivy jsou vloženy do sestavení PresentationFramework a můžete na ně odkazovat pomocí identifikátorů URI balíčků ve slovníkech prostředků vaší aplikace.

Pokud chcete použít předdefinovaný motiv, sloučte knihovnu zdrojů motivu do zdrojů aplikace v 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>

Dostupné předdefinované motivy

Následující tabulka uvádí předdefinované motivy dostupné prostřednictvím identifikátorů URI balíčků:

Theme Identifikátor URI balíčku Popis
Aero2 /PresentationFramework.Aero2;component/themes/Aero2.NormalColor.xaml Výchozí motiv pro aplikace pro Windows 8 a novější.
AeroLite /PresentationFramework.AeroLite;component/themes/AeroLite.NormalColor.xaml Zjednodušená verze Aero2 s omezenými vizuálními efekty.
Aero /PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml Motiv z období Windows 7 s efekty skla a gradienty.
Plynně /PresentationFramework.Fluent;component/Themes/Fluent.xaml Motiv ve stylu Windows 11 s podporou světlého/tmavého režimu (.NET 9+).
Luna (modrá) /PresentationFramework.Luna;component/themes/Luna.NormalColor.xaml Výchozí modré barevné schéma systému Windows XP
Luna (Silver) /PresentationFramework.Luna;component/themes/Luna.Metallic.xaml Barevné schéma Windows XP kovově stříbrné.
Luna (Oliva) /PresentationFramework.Luna;component/themes/Luna.Homestead.xaml Windows XP olivově zelené barevné schéma.
Royale /PresentationFramework.Royale;component/themes/Royale.NormalColor.xaml Téma Windows XP Media Center Edition.
Classic /PresentationFramework.Classic;component/themes/Classic.xaml Tradiční vzhled Windows 95/98/2000.

Poznámka:

U aplikací rozhraní .NET Framework možná budete muset v projektu přidat odkazy na sestavení vzhledu (například PresentationFramework.Aero2). U aplikací .NET jsou sestavení tématu obvykle zahrnuta automaticky.

Návod

Visual Studio obsahuje soubory XAML pro tyto motivy v instalačním adresáři, obvykle umístěné v umístění C:\Program Files\Microsoft Visual Studio\2022\<edition>\DesignTools\SystemThemes\wpf. Tyto soubory jsou užitečné pro pochopení struktury motivu, ale nepoužívají se za běhu.

Použití moderního motivu Fluent (.NET 9+)

Pro .NET 9 a novější můžete použít nový motiv Fluent, který podporuje světlé a tmavé režimy:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Alternativně můžete vlastnost použít ThemeMode pro ještě jednodušší aplikaci motivu:

<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>

Viz také