XAML-Formatvorlagen

Das XAML-Framework bietet zahlreiche Anpassungsmöglichkeiten für die App-Darstellung. Sie können mit Stilen die Steuerelementeigenschaften festlegen und diese Einstellungen dann für andere Steuerelemente übernehmen, um so für ein einheitliches Erscheinungsbild zu sorgen.

WinUI und Stile

Ab WinUI 2.2 haben wir die Windows UI Library (WinUI) verwendet, um neue visuelle Stilupdates für unsere UI-Komponenten bereitzustellen. Wenn Sie feststellen, dass Ihre Benutzeroberfläche nicht auf die neuesten Stile aktualisiert wird, stellen Sie sicher, dass Sie auf das neueste WinUI-NuGet-Paket aktualisieren.

Ab WinUI 2.6 bieten wir neue Stile für die meisten Steuerelemente und ein neues Versionsverwaltungssystem, mit dem Sie bei Bedarf zu den vorherigen Steuerelementstilen rückgängig machen können. Wir empfehlen Ihnen, die neuen Stile zu verwenden, da sie besser mit der Entwurfsrichtung von Windows übereinstimmen. Wenn Ihr Szenario die neuen Stile jedoch nicht unterstützen kann, sind die vorherigen Versionen weiterhin verfügbar.

Sie können die Formatvorlagenversion ändern, indem Sie die ControlsResourcesVersion -Eigenschaft für die festlegen, die XamlControlsResources Sie bei Verwendung von WinUI-Version 2 in Ihr Application.Resources einschließen. ControlsResourcesVersion wird standardmäßig auf den Enumerationswert festgelegt Version2.

Wenn Sie diesen Wert auf Version1 festlegen, werden XamlControlsResources die vorherigen Stilversionen anstelle der neuen Formatvorlagen geladen, die von der neuesten WinUI-Version verwendet werden. Das Ändern dieser Eigenschaft zur Laufzeit wird nicht unterstützt, und die Hot Reload-Funktionalität von VisualStudio funktioniert nicht. Nachdem Sie Ihre Anwendung neu erstellt haben, sehen Sie jedoch, dass sich die Steuerelementstile ändern.

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

Grundlagen zu Stilen

Verwenden Sie Stile, um visuelle Eigenschaften in wiederverwendbare Ressourcen auszulagern. Dieses Beispiel zeigt drei Schaltflächen mit einem Stil, der die Eigenschaften BorderBrush, BorderThickness und Foreground festlegt. Durch Anwenden eines Stils können Sie eine einheitliche Darstellung der Steuerelemente erreichen, ohne diese Eigenschaften separat für jedes Steuerelement festlegen zu müssen.

Screenshot der drei formatierten, nebeneinander angeordneten Schaltflächen.

Sie können einen Stil inline im XAML-Code für ein Steuerelement oder als wiederverwendbare Ressource definieren. Sie können Ressourcen in der XAML-Datei einer bestimmten Seite, in der Datei App.xaml oder in einer separaten XAML-Datei mit Ressourcenverzeichnis definieren. Eine XAML-Datei mit einem Ressourcenverzeichnis kann App-übergreifend genutzt werden. Außerdem können in einer einzelnen App mehrere Ressourcenverzeichnisse zusammengeführt werden. Der Ort, an dem die Ressource definiert wird, bestimmt den Bereich, in dem sie verwendet werden kann. Ressourcen auf Seitenebene sind nur auf der Seite verfügbar, für die sie definiert sind. Sind Ressourcen mit demselben Schlüssel sowohl in „App.xaml“ als auch auf einer Seite definiert, haben die Ressourcen auf der Seite Vorrang vor den Ressourcen in App.xaml. Wenn eine Ressource in einer separaten Ressourcenwörterbuchdatei definiert ist, wird Ihr Bereich dadurch bestimmt, von wo auf das Ressourcenwörterbuch verwiesen wird.

In der Style-Definition benötigen wir ein TargetType-Attribut und eine Auflistung mit einem oder mehreren Setter-Elementen. Das TargetType-Attribut ist eine Zeichenfolge, die einen FrameworkElement-Typ angibt, auf den der Stil angewendet wird. Der TargetType-Wert muss einen von FrameworkElement abgeleiteten Typ angeben, der durch die Windows-Runtime definiert ist, oder einen benutzerdefinierten Typ, der in einer referenzierten Assembly verfügbar ist. Wenn Sie versuchen, einen Stil auf ein Steuerelement anzuwenden, das nicht zum TargetType-Attribut des Stils passt, der angewendet werden soll, wird eine Ausnahme ausgelöst.

Jedes Setter-Element benötigt eine Property und einen Value. Diese Eigenschaftseinstellungen geben die Steuerelementeigenschaft an, auf die die Einstellung angewendet wird, und den Wert, der für diese Eigenschaft festgelegt wird. Sie können den Setter.Value entweder mit Attribut- oder Eigenschaftselementsyntax angeben. Dieses XAML-Codebeispiel zeigt den Stil, der auf die zuvor abgebildeten Schaltflächen angewendet wurde. In diesem XAML-Code verwenden die ersten beiden Setter-Elemente Attributsyntax, aber der letzte Setter (für die BorderBrush-Eigenschaft) verwendet Eigenschaftselementsyntax. Bei diesem Beispiel wird das x:Key-Attribut nicht verwendet, sodass der Stil implizit auf die Schaltflächen angewendet wird. Das implizite oder explizite Anwenden von Stilen wird im nächsten Abschnitt beschrieben.

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

Anwenden impliziter oder expliziter Stile

Wenn Sie einen Stil als Ressource definieren, können Sie ihn auf zwei Arten auf Ihre Steuerelemente anwenden:

Wenn ein Stil ein x:Key-Attribut enthält, können Sie ihn nur auf Steuerelemente anwenden, indem Sie die Style-Eigenschaft des Steuerelements auf den Stilschlüssel festlegen. Im Gegensatz dazu wird ein Stil ohne x:Key-Attribut automatisch auf jedes Steuerelement mit dem Zieltyp angewendet, das ansonsten über keine explizite Stileinstellung verfügt.

Diese beiden Schaltflächen veranschaulichen implizite und explizite Stile.

Schaltflächen mit impliziten und expliziten Stilen

In diesem Beispiel besitzt der erste Stil ein x:Key-Attribut, und der Zieltyp ist Button. Die Style-Eigenschaft der ersten Schaltfläche wird auf diesen Schlüssel festgelegt, sodass der Stil explizit angewendet wird. Der zweite Stil wird implizit auf die zweite Schaltfläche angewendet, da deren Zieltyp Button ist und der Stil kein x:Key-Attribut besitzt.

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

Verwenden abgeleiteter Stile

Um die Verwaltung von Stilen zu vereinfachen und die Wiederverwendung zu optimieren, können Sie Stile erstellen, die von anderen Stilen erben. Verwenden Sie die BasedOn-Eigenschaft, um abgeleitete Stile zu erstellen. Stile, die von anderen Stilen erben, müssen als Ziel denselben Steuerelementtyp haben oder ein Steuerelement, das von dem Typ abgeleitet wird, auf den der Basisstil verweist. Wenn das Ziel des Basisstils z. B. ContentControl ist, können die von diesem abgeleiteten Stile ContentControl als Ziel haben oder Typen, die von ContentControl abgeleitet sind, z. B. Button und ScrollViewer. Wenn ein Wert im abgeleiteten Stil nicht festgelegt wurde, wird er vom Basisstil vererbt. Möchten Sie den Wert vom Basisstil ändern, können Sie ihn im abgeleiteten Stil überschreiben. Das nächste Beispiel zeigt einen Button und ein CheckBox mit Stilen, die von demselben Basisstil abgeleitet sind.

Formatierte Schaltflächen mit abgeleiteten Stilen

Der Basisstil hat als Ziel ContentControl. Er legt die Height-Eigenschaft und die Width-Eigenschaft fest. Die von diesem Stil abgeleiteten Stile haben als Ziel CheckBox und Button, die von ContentControl abgeleitet sind. Die abgeleiteten Stile legen andere Farben für die BorderBrush-Eigenschaft und die Foreground-Eigenschaft fest. (In der Regel wird ein CheckBox-Element nicht um einen Rahmen gelegt. Wir tun es hier, um die Auswirkungen des Stils zu zeigen.)

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

Verwenden von Tools für die problemlose Arbeit mit Stilen

Wenn Sie schnell einen Stil auf Ihr Steuerelement anwenden möchten, klicken Sie auf der Microsoft Visual Studio XAML-Entwicklungsoberfläche mit der rechten Maustaste auf das Steuerelement, und wählen Sie Stil bearbeiten oder Vorlage bearbeiten aus (je nach Steuerelement). Anschließend können Sie einen vorhandenen Stil anwenden, indem Sie Ressource übernehmen auswählen, oder einen neuen erstellen, indem Sie Leer erstellen auswählen. Wenn Sie einen leeren Stil erstellen, haben Sie die Möglichkeit, diesen auf der Seite, in der Datei App.xaml oder in einem eigenen Ressourcenverzeichnis zu definieren.

Einfache Formatierung

Das Überschreiben der Systempinsel geschieht gewöhnlich auf App- oder Seitenebene, und in keinem Fall wirkt sich die Farbüberschreibung auf alle Steuerelemente aus, die auf diesen Pinsel verweisen – und in XAML können zahlreiche Steuerelemente auf denselben Pinsel verweisen.

Screenshot von zwei Schaltflächen: eine im Ruhezustand und eine mit angewendeter einfacher Formatierung.

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

Für Zustände wie PointerOver (Mauszeiger über der Schaltfläche), PointerPressed (Schaltfläche betätigt) oder Deaktiviert (Schaltfläche erlaubt keine Interaktion). Diese Enden werden an die ursprünglichen Lightweight-Formatnamen angefügt: ButtonBackgroundPointerOver, ButtonForegroundPressed, ButtonBorderBrushDisabled usw. Wenn Sie auch diese Pinsel ändern, stellen Sie sicher, dass Ihre Steuerelemente konsistent dem Design Ihrer App entsprechen.

Die Verwendung dieser Pinselüberschreibungen auf der App.Resources-Ebene verändert alle Schaltflächen in der gesamten App und nicht nur auf einer Seite.

Formatierung pro Steuerelement

In anderen Fällen ist es möglicherweise erwünscht, nur ein einzelnes Steuerelement auf einer Seite in einer bestimmten Weise zu gestalten, ohne dass dies andere Versionen dieses Steuerelements betrifft:

Screenshot von drei formatierten, übereinander gestapelt angeordneten Schaltflächen.

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

Dies würde sich nur auf ein "Spezielles CheckBox" auf der Seite auswirken, auf der dieses Steuerelement vorhanden war.

Benutzerdefinierte Steuerelemente

Wenn Sie Ihre eigenen benutzerdefinierten Steuerelemente erstellen, die visuell und/oder funktionell an unseren integrierten Steuerelementen ausgerichtet sind, sollten Sie die Verwendung impliziter Formatierungsressourcen und Ressourcen für einfache Formatierung in Betracht ziehen, um Ihre benutzerdefinierten Inhalte zu definieren. Sie können die Ressourcen entweder direkt verwenden oder einen neuen Alias für die Ressource erstellen.

Direktes Verwenden von Steuerungsressourcen

Wenn Sie z. B. ein Steuerelement schreiben, das wie eine Schaltfläche aussieht, können Sie das Steuerelement wie folgt direkt auf die Schaltflächenressourcen verweisen lassen:

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

Aliasing von Steuerelementressourcen in neue Namen

Wenn Sie lieber eigene Ressourcen erstellen möchten, sollten Sie diese benutzerdefinierten Namen auch als Alias für unsere Standardmäßigen Lightweight-Formatierungsressourcen verwenden.

Der Stil Ihres benutzerdefinierten Steuerelements kann z. B. spezielle Ressourcendefinitionen aufweisen:

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

In Ihrem Ressourcenwörterbuch oder Standard Definition würden Sie die Lightweight-Formatierungsressourcen mit Ihren benutzerdefinierten Ressourcen verbinden:

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

Es ist erforderlich, dass Sie ein ThemeDictionary verwenden, das dreimal dupliziert wird, um die drei verschiedenen Designänderungen ordnungsgemäß zu behandeln (Default, Light, HighContrast).

Achtung

Wenn Sie einem neuen Alias eine Lightweight-Formatierungsressource zuweisen und auch die Lightweight-Formatierungsressource neu definieren, wird Ihre Anpassung möglicherweise nicht angewendet, wenn die Ressourcensuche nicht in der richtigen Reihenfolge ausgeführt wird. Wenn Sie z. B. an einer Stelle überschreiben ButtonBackground , die vor dem MyCustomControlBackground Gefundenen durchsucht wird, wird die Außerkraftsetzung übersehen.

Vermeiden von Restyling-Steuerelementen

Die Windows-Benutzeroberflächenbibliothek 2.2 oder höher enthält neue Stile und Vorlagen für WinUI- und Systemsteuerelemente.

Die beste Möglichkeit, mit unseren neuesten visuellen Stilen auf dem neuesten Stand zu bleiben, besteht darin, das neueste WinUI 2-Paket zu verwenden und benutzerdefinierte Stile und Vorlagen (auch als Neuvorlagen bezeichnet) zu vermeiden. Stile sind immer noch eine bequeme Möglichkeit, eine Reihe von Werten konsistent auf Steuerelemente in Ihrer App anzuwenden. Wenn Sie dies tun, stellen Sie sicher, dass Sie auf unseren neuesten Stilen basieren.

Legen Sie für Systemsteuerelemente, die WinUI-Stile (Windows.UI.Xaml.Controls Namespace) verwenden, fest BasedOn="{StaticResource Default<ControlName>Style}", wobei <ControlName> der Name des Steuerelements ist. Beispiel:

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

Für WinUI 2-Steuerelemente (Microsoft.UI.Xaml.Controls Namespace) wird der Standardstil in den Metadaten definiert, daher lassen Sie aus BasedOn.

Abgeleitete Steuerelemente

Wenn Sie ein benutzerdefiniertes Steuerelement von einem vorhandenen XAML-Steuerelement ableiten, werden die WinUI 2-Formatvorlagen standardmäßig nicht abgerufen. So wenden Sie die WinUI 2-Formatvorlagen an:

  • Erstellen Sie eine neue Formatvorlage , wobei targetType auf Ihr benutzerdefiniertes Steuerelement festgelegt ist.
  • Basieren Sie die Formatvorlage auf dem Standardformat des Steuerelements, von dem Sie abgeleitet haben.

Ein gängiges Szenario hierfür ist das Ableiten eines neuen Steuerelements von ContentDialog. In diesem Beispiel wird gezeigt, wie Sie eine neue Formatvorlage erstellen, die für Ihr benutzerdefiniertes Dialogfeld gilt DefaultContentDialogStyle .

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

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

Die Eigenschaft eines Templates

Für die Template-Eigenschaft eines Control-Elements kann ein Stilsetter verwendet werden. Dieser erstellt letztendlich den größten Teil eines typischen XAML-Stils und der XAML-Ressourcen einer App. Eine ausführlichere Beschreibung finden Sie im Thema Steuerelementvorlagen.