{ThemeResource}-Markuperweiterung
Stellt einen Wert für jedes XAML-Attribut bereit, indem ein Verweis auf eine Ressource ausgewertet wird, mit zusätzlicher Systemlogik, die je nach aktuell aktivem Design unterschiedliche Ressourcen abruft. Ähnlich wie die {StaticResource}-Markuperweiterung werden Ressourcen in einem ResourceDictionary definiert, und eine ThemeResource-Verwendung verweist auf den Schlüssel dieser Ressource im ResourceDictionary.
XAML-Attributsyntax
<object property="{ThemeResource key}" .../>
XAML-Werte
Begriff | Beschreibung |
---|---|
Schlüssel | Der Schlüssel für die angeforderte Ressource. Dieser Schlüssel wird zunächst vom ResourceDictionary zugewiesen. Ein Ressourcenschlüssel kann eine beliebige in der XamlName-Grammatik definierte Zeichenfolge sein. |
Hinweise
Eine ThemeResource ist eine Technik zum Abrufen von Werten für ein XAML-Attribut, die an anderer Stelle in einem XAML-Ressourcenwörterbuch definiert sind. Die Markuperweiterung dient dem gleichen grundlegenden Zweck wie die {StaticResource}-Markuperweiterung. Der Unterschied im Verhalten gegenüber der {StaticResource}-Markuperweiterung besteht darin, dass ein ThemeResource-Verweis verschiedene Wörterbücher dynamisch als primären Nachschlageort verwenden kann, je nachdem, welches Design derzeit vom System verwendet wird.
Wenn die App zum ersten Mal gestartet wird, wird jeder Ressourcenverweis, der von einem ThemeResource-Verweis erstellt wird, basierend auf dem Design ausgewertet, das beim Start verwendet wird. Wenn der Benutzer das aktive Design jedoch zur Laufzeit ändert, wertet das System alle ThemeResource-Verweise erneut aus, ruft eine designspezifische Ressource ab, die möglicherweise anders sein kann, und zeigt die App an allen geeigneten Stellen in der visuellen Struktur erneut an. Eine StaticResource wird zum XAML-Ladezeitpunkt /App-Start bestimmt und wird zur Laufzeit nicht erneut ausgewertet. (Es gibt andere Techniken wie visuelle Zustände, die XAML dynamisch neu laden, aber diese Techniken funktionieren auf einer höheren Ebene, als die grundlegende Ressourcenauswertung durch {StaticResource}-Markuperweiterung).
ThemeResource verwendet ein Argument, das den Schlüssel für die angeforderte Ressource angibt. Ein Ressourcenschlüssel ist immer eine Zeichenfolge in Windows-Runtime XAML. Weitere Informationen dazu, wie der Ressourcenschlüssel anfänglich angegeben wird, finden Sie unter "x:Key"-Attribut.
Weitere Informationen zum Definieren von Ressourcen und zur ordnungsgemäßen Verwendung eines ResourceDictionary, einschließlich Beispielcode, finden Sie unter ResourceDictionary- und XAML-Ressourcenverweise.
Wichtig wie bei StaticResource darf eine ThemeResource nicht versuchen, einen Vorwärtsverweis auf eine Ressource vorzunehmen, die in der XAML-Datei lexikalisch definiert ist. Der Versuch, dies zu tun, wird nicht unterstützt. Auch wenn der Vorwärtsverweis nicht fehlschlägt, führt der Versuch, eine Leistungseinbuße zu erzielen. Um optimale Ergebnisse zu erzielen, passen Sie die Zusammensetzung Ihrer Ressourcenwörterbücher so an, dass Vorwärtsverweise vermieden werden.
Beim Versuch, eine ThemeResource für einen Schlüssel anzugeben, der nicht aufgelöst werden kann, wird zur Laufzeit eine XAML-Analyseausnahme ausgelöst. Designtools können auch Warnungen oder Fehler enthalten.
In der Windows-Runtime XAML-Prozessorimplementierung gibt es keine Sicherungsklassendarstellung für ThemeResource. Die nächstgelegene Entsprechung im Code besteht darin, die Sammlungs-API eines ResourceDictionary zu verwenden, z. B. "Contains" oder "*TryGetValue".
ThemeResource ist eine Markuperweiterung. Markuperweiterungen werden in der Regel implementiert, wenn Attributwerte mit Escapezeichen versehen werden müssen, damit diese nicht als literale Werte oder als Handlernamen betrachtet werden, und diese Anforderung eher global und nicht nur durch den Einsatz von Typkonvertern für bestimmte Typen oder Eigenschaften erfüllt werden soll. Alle Markuperweiterungen in XAML verwenden die Zeichen "{" und "}" in ihrer Attributsyntax. Dies ist die Konvention, mit der ein XAML-Prozessor erkennt, dass eine Markuperweiterung das Attribut verarbeiten muss.
Wann und wie {ThemeResource} anstelle von {StaticResource} verwendet wird
Die Regeln, nach denen eine ThemeResource in ein Element in einem Ressourcenwörterbuch aufgelöst wird, sind im Allgemeinen mit StaticResource identisch. Eine ThemeResource-Suche kann in die ResourceDictionary-Dateien erweitert werden, auf die in einer ThemeDictionaries-Auflistung verwiesen wird, aber eine StaticResource kann dies auch tun. Der Unterschied besteht darin, dass eine ThemeResource zur Laufzeit neu ausgewertet werden kann und eine StaticResource nicht möglich ist.
Der Satz von Schlüsseln in jedem Designwörterbuch sollte unabhängig davon, welches Design aktiv ist, den gleichen Satz von Schlüsselressourcen bereitstellen. Wenn eine bestimmte Schlüsselressource im Designverzeichnis "HighContrast " vorhanden ist, sollte auch eine andere Ressource mit diesem Namen in Light und Default vorhanden sein. Wenn dies nicht der Fall ist, schlägt die Ressourcensuche möglicherweise fehl, wenn der Benutzer Designs wechselt und Ihre App nicht richtig aussieht. Es ist jedoch möglich, dass ein Designwörterbuch Schlüsselressourcen enthalten kann, auf die nur innerhalb desselben Bereichs verwiesen wird, um Unterwerte bereitzustellen; Diese müssen in allen Designs nicht gleichwertig sein.
Im Allgemeinen sollten Sie Ressourcen in Designwörterbüchern platzieren und Verweise auf diese Ressourcen mit ThemeResource nur erstellen, wenn diese Werte zwischen Designs geändert werden können oder von Werten unterstützt werden, die sich ändern. Dies ist für diese Arten von Ressourcen geeignet:
- Pinsel, insbesondere Farben für SolidColorBrush. Diese bilden etwa 80 % der ThemeResource-Verwendungen in den Standard-XAML-Steuerelementvorlagen (generic.xaml).
- Pixelwerte für Rahmen, Offsets, Rand und Abstand usw.
- Schriftarteigenschaften wie FontFamily oder FontSize.
- Vollständige Vorlagen für eine begrenzte Anzahl von Steuerelementen, die in der Regel systemformatiert sind und für dynamische Präsentationen verwendet werden, z. B. GridViewItem und ListViewItem.
- Textanzeigeformate (in der Regel zum Ändern der Schriftfarbe, des Hintergrunds und eventueller Größe).
Die Windows-Runtime stellt eine Reihe von Ressourcen bereit, auf die speziell von ThemeResource verwiesen werden soll. Diese werden alle als Teil der XAML-Datei themeresources.xaml aufgeführt, die im Ordner include/winrt/xaml/design im Rahmen des Windows Software Development Kit (SDK) verfügbar ist. Dokumentation zu den Designpinseln und zusätzlichen Formatvorlagen, die in themeresources.xaml definiert sind, finden Sie unter XAML-Designressourcen. Die Pinsel werden in einer Tabelle dokumentiert, die Ihnen angibt, über welchen Farbwert jeder Pinsel für jedes der drei möglichen aktiven Designs verfügt.
Die XAML-Definitionen visueller Zustände in einer Steuerelementvorlage sollten ThemeResource-Verweise verwenden, wenn eine zugrunde liegende Ressource vorhanden ist, die sich aufgrund einer Designänderung ändern kann. Eine Systemdesignänderung führt in der Regel nicht auch zu einer Änderung des visuellen Zustands. Die Ressourcen müssen ThemeResource-Verweise in diesem Fall verwenden, damit Werte für den weiterhin aktiven visuellen Zustand neu ausgewertet werden können. Wenn Sie z. B. einen visuellen Zustand haben, der eine Pinselfarbe eines bestimmten UI-Teils und eine seiner Eigenschaften ändert und diese Pinselfarbe pro Design unterschiedlich ist, sollten Sie einen ThemeResource-Verweis verwenden, um den Wert dieser Eigenschaft in der Standardvorlage und auch alle Änderungen des visuellen Zustands an dieser Standardvorlage bereitzustellen.
ThemeResource-Verwendungen können in einer Reihe von abhängigen Werten angezeigt werden. Beispielsweise kann ein von einem SolidColorBrush verwendeter Farbwert, der auch eine Schlüsselressource ist, einen ThemeResource-Verweis verwenden. Aber alle UI-Eigenschaften, die die keyed SolidColorBrush-Ressource verwenden, würden auch einen ThemeResource-Verweis verwenden, sodass es sich speziell um jede Pinseltypeigenschaft handelt, die eine dynamische Wertänderung ermöglicht, wenn sich das Design ändert.
Hinweis{ThemeResource}
und Laufzeitressourcenauswertung beim Wechseln von Designs werden in Windows 8.1-XAML unterstützt, aber nicht in XAML für Apps für Windows 8 unterstützt.
Systemressourcen
Einige Designressourcen verweisen auf Systemressourcenwerte als zugrunde liegenden Unterwert. Eine Systemressource ist ein spezieller Ressourcenwert, der in keinem XAML-Ressourcenwörterbuch gefunden wird. Diese Werte basieren auf dem Verhalten in Windows-Runtime XAML-Unterstützung zum Weiterleiten von Werten aus dem System selbst und stellen sie in einer Form dar, auf die eine XAML-Ressource verweisen kann. Beispielsweise gibt es eine Systemressource namens "SystemColorButtonFaceColor", die eine RGB-Farbe darstellt. Diese Farbe stammt aus den Aspekten von Systemfarben und Designs, die nicht nur für Windows-Runtime und Windows-Runtime Apps spezifisch sind.
Systemressourcen sind häufig die zugrunde liegenden Werte für ein Design mit hohem Kontrast. Der Benutzer hat die Kontrolle über die Farbauswahl für sein Design mit hohem Kontrast, und der Benutzer trifft diese Auswahl mithilfe von Systemfeatures, die auch nicht für Windows-Runtime Apps spezifisch sind. Durch Verweisen auf die Systemressourcen als ThemeResource-Verweise kann das Standardverhalten der Designs mit hohem Kontrast für Windows-Runtime Apps diese designspezifischen Werte verwenden, die vom Benutzer gesteuert und vom System verfügbar gemacht werden. Außerdem werden die Verweise jetzt für die erneute Auswertung markiert, wenn das System eine Laufzeitdesignänderung erkennt.
Beispiel für eine {ThemeResource}-Verwendung
Nachfolgend finden Sie ein Beispiel-XAML aus den Standarddateien "generic.xaml" und "themeresources.xaml", um zu veranschaulichen, wie ThemeResource verwendet wird. Wir betrachten nur eine Vorlage (die Standardschaltfläche) und wie zwei Eigenschaften deklariert werden (Hintergrund und Vordergrund), um auf Designänderungen reagieren zu können.
<!-- Default style for Windows.UI.Xaml.Controls.Button -->
<Style TargetType="Button">
<Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForegroundThemeBrush}"/>
...
Hier nehmen die Eigenschaften einen Pinselwert und den Verweis auf solidColorBrush-Ressourcen namens ButtonBackgroundThemeBrush
und ButtonForegroundThemeBrush
werden mithilfe von ThemeResource erstellt.
Diese Eigenschaften werden auch von einigen visuellen Zuständen für eine Schaltfläche angepasst. Insbesondere ändert sich die Hintergrundfarbe, wenn auf eine Schaltfläche geklickt wird. Auch hier verwenden die Animationen "Hintergrund" und "Vordergrund" im Storyboard für den visuellen Zustand DiskretObjectKeyFrame-Objekte und Verweise auf Pinsel mit ThemeResource als Keyframewert.
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Jeder dieser Pinsel ist weiter oben in "generic.xaml" definiert: Sie mussten vor vorlagen definiert werden, um XAML-Weiterleitungsverweise zu vermeiden. Hier sind diese Definitionen für das Designwörterbuch "Standard".
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
...
<SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="#FFFFFFFF" />
...
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="#FF000000" />
...
Anschließend sind alle anderen Designwörterbücher auch für diese Pinsel definiert, z. B.:
<ResourceDictionary x:Key="HighContrast">
<!-- High Contrast theme resources -->
...
<SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
<SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />
...
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />
<SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
Hier ist der Farbwert ein weiterer ThemeResource-Verweis auf eine Systemressource. Wenn Sie auf eine Systemressource verweisen und als Reaktion auf eine Designänderung ändern möchten, sollten Sie ThemeResource verwenden, um den Verweis vorzunehmen.
Windows 8-Verhalten
Windows 8 unterstützt die ThemeResource-Markuperweiterung nicht, sie ist ab Windows 8.1 verfügbar. Außerdem hat Windows 8 das dynamische Wechseln der designbezogenen Ressourcen für eine Windows-Runtime-App nicht unterstützt. Die App musste neu gestartet werden, um die Designänderung für die XAML-Vorlagen und -Stile aufzunehmen. Dies ist keine gute Benutzererfahrung, daher werden Apps dringend empfohlen, Windows 8.1 neu zu kompilieren und als Ziel festzulegen, damit sie Stile mit ThemeResource-Verwendungen verwenden und Designs dynamisch wechseln können, wenn der Benutzer dies tut. Apps, die für Windows 8 kompiliert wurden, aber unter Windows 8.1 ausgeführt werden, verwenden weiterhin das Windows 8-Verhalten.
Unterstützung von Entwurfszeittools für die {ThemeResource} -Markuperweiterung
Microsoft Visual Studio 2013 kann mögliche Schlüsselwerte in die Microsoft IntelliSense-Dropdowns einschließen, wenn Sie die Markuperweiterung {ThemeResource} auf einer XAML-Seite verwenden. Sobald Sie z. B. "{ThemeResource" eingeben, werden alle Ressourcenschlüssel aus den XAML-Designressourcen angezeigt.
Sobald ein Ressourcenschlüssel als Teil einer {ThemeResource} -Verwendung vorhanden ist, kann das Feature "Gehe zu Definition (F12)" diese Ressource auflösen und Ihnen die "generic.xaml" für die Entwurfszeit anzeigen, in der die Designressource definiert ist. Da Designressourcen mehr als einmal (pro Design) definiert sind, gelangen Sie zu der ersten Definition, die in der Datei gefunden wurde. Dies ist die Definition für "Standard". Wenn Sie die anderen Definitionen verwenden möchten, können Sie innerhalb der Datei nach dem Schlüsselnamen suchen und die Definitionen der anderen Designs finden.