XAML-Stile

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 Formatvorlagen

Ab WinUI 2.2 haben wir WinUI verwendet, um neue visuelle Formatvorlagenaktualisierungen für alle unsere UI-Komponenten bereitzustellen. Wenn Sie feststellen, dass Ihre Benutzeroberfläche nicht auf die neuesten Formatvorlagen aktualisiert wird, aktualisieren Sie unbedingt auf das neueste WinUI-NuGet-Paket.

Ab WinUI 2.6 stellen wir für die meisten Steuerelemente neue Formatvorlagen bereit und ein neues Versionierungssystem, mit dem Sie bei Bedarf zu den vorherigen Steuerelementformatvorlagen zurückkehren können. Wir empfehlen Ihnen, die neuen Formatvorlagen zu verwenden, da diese besser zur Designrichtung von Windows passen. Wenn Ihr Szenario die neuen Formatvorlagen jedoch nicht unterstützen kann, sind die vorherigen Versionen weiterhin verfügbar.

Sie können die Formatvorlagenversion ändern, indem Sie die ControlsResourcesVersion-Eigenschaft in XamlControlsResources festlegen, die Sie in Application.Resources einbeziehen, wenn Sie WinUI Version 2 verwenden. ControlsResourcesVersion hat standardmäßig den Enumerationswert Version2.

Durch Festlegen dieses Werts auf Version1 werden XamlControlsResources die vorherigen Formatvorlagenversionen 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-Funktion von VisualStudio funktioniert nicht. Nachdem Sie die Anwendung neu erstellt haben, werden die Steuerelementformatvorlagen jedoch geändert.

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

Grundlagen zu Formatvorlagen

Verwenden Sie Formatvorlagen, um visuelle Eigenschafteneinstellungen in wiederverwendbare Ressourcen zu extrahieren. Dieses Beispiel zeigt drei Schaltflächen mit einem Stil, der die Eigenschaften BorderBrush, BorderThickness und Foreground festlegt. Wenn Sie eine Formatvorlage anwenden, können Sie festlegen, dass die Steuerelemente gleich angezeigt werden, ohne diese Eigenschaften für jedes Steuerelement separat festlegen zu müssen.

Screenshot der drei formatierten, nebeneinander angeordneten Schaltflächen.

Sie können eine Formatvorlage inline im XAML für ein Steuerelement oder als wiederverwendbare Ressource definieren. Definieren Sie Ressourcen in der XAML-Datei einer einzelnen Seite, in der Datei „App.xaml“ oder in einer separaten XAML-Datei des Ressourcenwörterbuchs. Eine XAML-Datei des Ressourcenwörterbuchs kann über Apps hinweg freigegeben werden, und mehrere Ressourcenwörterbücher können in einer einzelnen App zusammengeführt werden. Die Position, an der die Ressource definiert ist, bestimmt den Bereich, in dem sie verwendet werden kann. Ressourcen auf Seitenebene sind nur auf der Seite verfügbar, auf der sie definiert sind. Wenn Ressourcen mit demselben Schlüssel sowohl in „App.xaml“ als auch auf einer Seite definiert sind, überschreibt die Ressource auf der Seite die Ressource 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 FrameworkElement-abgeleiteten Typ angeben, der durch die Windows-Runtime definiert wird, oder einen benutzerdefinierten Typ, der in einer referenzierten Assembly verfügbar ist. Wenn Sie versuchen, eine Formatvorlage auf ein Steuerelement anzuwenden und der Typ des Steuerelements nicht mit dem TargetType-Attribut der Formatvorlage übereinstimmt, die Sie anwenden möchten, tritt eine Ausnahme auf.

Jedes Setter-Element benötigt eine Property und einen Value. Diese Eigenschafteneinstellungen geben an, auf welche Steuerelementeigenschaft die Einstellung angewendet wird, und welcher Wert für diese Eigenschaft festgelegt werden soll. Sie können Setter.Value entweder mit Attribut- oder Eigenschaftselementsyntax festlegen. Das XAML zeigt die Formatvorlage, die auf die zuvor angezeigten 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. Im Beispiel wird nicht das x:Key attribute-Attribut verwendet, sodass die Formatvorlage implizit auf die Schaltflächen angewendet wird. Das implizite oder explizite Anwenden von Formatvorlagen wird im nächsten Abschnitt erläutert.

<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 einer impliziten oder expliziten Formatvorlage

Wenn Sie eine Formatvorlage als Ressource definieren, gibt es zwei Möglichkeiten, sie auf Ihre Steuerelemente anzuwenden:

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 eine Formatvorlage ohne ein x:Key-Attribut automatisch auf jedes Steuerelement des Zieltyps angewendet, das andernfalls keine explizite Formatvorlageneinstellung aufweist.

Hier sind zwei Schaltflächen, die implizite und explizite Formatvorlagen veranschaulichen.

Implizit und explizit formatierte Schaltflächen.

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. Die zweite Formatvorlage wird implizit auf die zweite Schaltfläche angewendet, da deren Zieltyp Button lautet und die Formatvorlage kein x:Key-Attribut hat.

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

Basierend auf Formatvorlagen verwenden

Damit Formatvorlagen einfacher zu verwalten sind und die Wiederverwendung von Formatvorlagen optimiert werden kann, können Sie Formatvorlagen erstellen, die von anderen Formatvorlagen erben. Verwenden Sie die BasedOn-Eigenschaft, um abgeleitete Stile zu erstellen. Formatvorlagen, die von anderen Formatvorlagen erben, müssen auf denselben Steuerelementtyp oder ein Steuerelement abzielen, das von dem Typ abgeleitet ist, auf den die Basisformatvorlage abzielt. 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 in der formatbasierten Vorlage kein Wert festgelegt wird, wird er von der Basisformatvorlage geerbt. Um einen Wert aus der Basisformatvorlage zu ändern, überschreibt die formatbasierte Vorlage diesen Wert. Das nächste Beispiel zeigt einen Button und ein CheckBox mit Stilen, die von demselben Basisstil abgeleitet sind.

Formatierte Schaltflächen, die formatbasierte Vorlagen verwenden

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. (Normalerweise setzen Sie keinen Rahmen um eine CheckBox. Hier dient es dazu, die Auswirkungen der Formatvorlage 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 zum einfachen Arbeiten mit Formatvorlagen

Eine schnelle Möglichkeit zum Anwenden von Formatvorlagen auf Ihre Steuerelemente besteht darin, mit der rechten Maustaste auf ein Steuerelement auf der XAML-Designoberfläche von Microsoft Visual Studio zu klicken und Formatvorlage bearbeiten oder Vorlage bearbeiten auszuwählen (abhängig von dem Steuerelement, auf das Sie mit der rechten Maustaste klicken). Anschließend können Sie eine vorhandene Formatvorlage anwenden, indem Sie Ressource anwenden oder eine neue Formatvorlage definieren, indem Sie Leer erstellen auswählen. Wenn Sie eine leere Formatvorlage erstellen, haben Sie die Möglichkeit, sie auf der Seite, in der Datei „App.xaml“ oder in einem separaten Ressourcenverzeichnis zu definieren.

Lightweight-Formatvorlage

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 (Maus wird über die Schaltfläche bewegt), PointerPressed (Schaltfläche wurde aufgerufen) oder Deaktiviert (Mit der Schaltfläche ist keine Interaktion möglich). Diese Endungen werden an die ursprünglichen einfachen Formatierungsnamen angefügt: ButtonBackgroundPointerOver, ButtonForegroundPressed, ButtonBorderBrushDisabled usw. Durch die Änderung dieser Pinsel wird sichergestellt, dass die Farbe Ihrer Steuerelemente dem Design Ihrer App entspricht.

Wenn Sie diese Pinselüberschreibungen auf der App.Resources-Ebene platzieren, werden alle Schaltflächen innerhalb der gesamten App und nicht auf einer einzelnen Seite geändert.

Formatieren pro Steuerelement

In anderen Fällen ist es erwünscht, nur ein einzelnes Steuerelement auf einer Seite so zu ändern, dass es ein bestimmtes Aussehen erhält, ohne andere Versionen dieses Steuerelements zu ändern:

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 das eine „spezielle Kontrollkästchen“ auf der Seite auswirken, auf der dieses Steuerelement vorhanden ist.

Benutzerdefinierte Steuerelemente

Wenn Sie Ihre eigenen benutzerdefinierten Steuerelemente erstellen, die möglicherweise visuell und/oder funktionell an unsere integrierten Steuerelemente ausgerichtet sind, sollten Sie die Verwendung impliziter Formatierungs- und Lightweight-Formatierungsressourcen 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 Steuerelementressourcen

Wenn Sie beispielsweise ein Steuerelement schreiben, das wie eine Schaltfläche aussieht, können Sie wie folgt auf die Schaltflächenressourcen verweisen:

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

Aliasing von Steuerelementressourcen für neue Namen

Wenn Sie alternativ Ihre eigenen Ressourcen erstellen möchten, sollten Sie diese benutzerdefinierten Namen unseren standardmäßigen Lightweight-Formatvorlagenressourcen zuweisen.

Die Formatvorlage des benutzerdefinierten Steuerelements kann beispielsweise 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 Ihrer Hauptdefinition würden Sie die Lightweight-Formatvorlagenressourcen mit Ihren benutzerdefinierten Ressourcen verknüpfen:

<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 einer neuen Alias-Ressource eine Lightweight-Formatvorlagenressource zuweisen und die Lightweight-Formatvorlagenressource außerdem neu definieren, wird Ihre Anpassung möglicherweise nicht angewendet, wenn die Ressourcensuche nicht in der richtigen Reihenfolge erfolgt. Wenn Sie beispielsweise ButtonBackground an einer Stelle überschreiben, die gesucht wird, bevor MyCustomControlBackground gefunden wird, würde das Überschreiben verfehlt werden.

Vermeiden von Umformatierungs-Steuerelementen

WinUI 2.2 oder höher enthält neue Formatvorlagen und Vorlagen für WinUI- und Systemsteuerelemente.

Die beste Möglichkeit, um über unsere aktuellen visuellen Formatvorlagen auf dem Laufenden zu bleiben, besteht darin, das neueste WinUI 2-Paket zu verwenden und benutzerdefinierte Formatvorlagen und Vorlagen (auch als erneute Vorlagenerstellung bezeichnet) zu vermeiden. Formatvorlagen sind immer noch eine bequeme Möglichkeit, eine Reihe von Werten konsistent über Steuerelemente in Ihrer App anzuwenden. Stellen Sie dabei sicher, dass diese auf unseren neuesten Formatvorlagen basieren.

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

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

Für WinUI 2-Steuerelemente (Microsoft.UI.Xaml.Controls-Namespace) wird die Standardformatvorlage in den Metadaten definiert, BasedOn kann also ausgelassen werden

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, deren TargetType auf Ihr benutzerdefiniertes Steuerelement festgelegt ist.
  • Basieren Sie die Formatvorlage auf der Standardformatvorlage des Steuerelements, von dem Sie abgeleitet haben.

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

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

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

Die template-Eigenschaft

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. Dies wird in den Steuerelementvorlagen ausführlicher erläutert.