Xamarin.Forms Ressourcenwörterbücher
A ResourceDictionary
ist ein Repository für Ressourcen, die von einer Xamarin.Forms Anwendung verwendet werden. Typische Ressourcen, die in einem ResourceDictionary
Format gespeichert sind, umfassen Formatvorlagen, Steuerelementvorlagen, Datenvorlagen, Farben und Konverter.
In XAML können ressourcen, die in einer ResourceDictionary
gespeichert sind, mithilfe der StaticResource
Erweiterung oder DynamicResource
Markuperweiterung auf Elemente verwiesen und angewendet werden. In C# können Ressourcen auch in einem ResourceDictionary
definiert werden und dann mit Hilfe eines stringbasierten Indexers auf Elemente verwiesen und angewendet werden. Es gibt jedoch wenig Vorteile bei der Verwendung einer ResourceDictionary
In C#, da freigegebene Objekte als Felder oder Eigenschaften gespeichert werden können und direkt darauf zugegriffen werden kann, ohne sie zuerst aus einem Wörterbuch abrufen zu müssen.
Erstellen von Ressourcen in XAML
Jedes VisualElement
abgeleitete Objekt verfügt über eine Resources
Eigenschaft, die eine ResourceDictionary
ist und Ressourcen enthalten kann. Ebenso verfügt ein abgeleitetes Application
Objekt über eine Resources
Eigenschaft, die ResourceDictionary
Ressourcen enthalten kann.
Eine Xamarin.Forms Anwendung enthält nur Eine Klasse, die von Application
dieser abgeleitet wird, verwendet jedoch häufig viele Klassen, die von VisualElement
Seiten, Layouts und Steuerelementen abgeleitet werden. Jedes dieser Objekte kann seine Resources
Eigenschaft auf eine ResourceDictionary
enthaltende Ressource festlegen. Die Wahl des Ortes, an dem ein bestimmtes ResourceDictionary
abgelegt wird, hat Auswirkungen darauf, wo die Ressourcen verwendet werden können:
- Ressourcen in einer
ResourceDictionary
Ansicht, die an eine Ansicht angefügt ist, zButton
. B. oderLabel
können nur auf dieses bestimmte Objekt angewendet werden. - Ressourcen in einem an ein
ResourceDictionary
Layout angefügten Layout,StackLayout
z. B. oderGrid
können auf das Layout und alle untergeordneten Elemente dieses Layouts angewendet werden. - Ressourcen in einer
ResourceDictionary
, die auf Seitenebene definiert sind, können auf die Seite und alle ihre Unterseiten angewendet werden. - Ressourcen,
ResourceDictionary
die auf Anwendungsebene definiert sind, können in der gesamten Anwendung angewendet werden.
Mit Ausnahme von impliziten Stilen muss jede Ressource im Ressourcenwörterbuch einen eindeutigen String-Schlüssel haben, der mit dem Attribut x:Key
definiert wird.
Der folgende XAML zeigt Ressourcen, die in einer Anwendungsebene ResourceDictionary
in der Datei App.xaml definiert sind:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.App">
<Application.Resources>
<Thickness x:Key="PageMargin">20</Thickness>
<!-- Colors -->
<Color x:Key="AppBackgroundColor">AliceBlue</Color>
<Color x:Key="NavigationBarColor">#1976D2</Color>
<Color x:Key="NavigationBarTextColor">White</Color>
<Color x:Key="NormalTextColor">Black</Color>
<!-- Implicit styles -->
<Style TargetType="{x:Type NavigationPage}">
<Setter Property="BarBackgroundColor"
Value="{StaticResource NavigationBarColor}" />
<Setter Property="BarTextColor"
Value="{StaticResource NavigationBarTextColor}" />
</Style>
<Style TargetType="{x:Type ContentPage}"
ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor"
Value="{StaticResource AppBackgroundColor}" />
</Style>
</Application.Resources>
</Application>
In diesem Beispiel definiert das Ressourcenverzeichnis eine Thickness
Ressource, mehrere Color
Ressourcen und zwei implizite Style
Ressourcen. Weitere Informationen zur App
Klasse finden Sie unter Xamarin.Forms App-Klasse.
Hinweis
Es ist auch gültig, alle Ressourcen zwischen expliziten ResourceDictionary
Tags zu platzieren. Da Xamarin.Forms jedoch 3.0 die ResourceDictionary
Tags nicht erforderlich sind. Stattdessen wird das ResourceDictionary
Objekt automatisch erstellt, und Sie können die Ressourcen direkt zwischen den Resources
Eigenschaftselementtags einfügen.
Ressourcen in XAML nutzen
Jede Ressource verfügt über einen Schlüssel, der mithilfe des x:Key
Attributs angegeben wird, das zu seinem Wörterbuchschlüssel in der ResourceDictionary
wird. Der Schlüssel wird verwendet, um auf eine Ressource aus der Mit- ResourceDictionary
StaticResource
oder DynamicResource
Markuperweiterung zu verweisen.
Die Markup-Erweiterung StaticResource
ähnelt der Markup-Erweiterung DynamicResource
insofern, als beide einen Wörterbuchschlüssel verwenden, um auf einen Wert aus einem Ressourcenwörterbuch zu verweisen. Während die Markup-Erweiterung StaticResource
jedoch nur eine einzige Wörterbuchsuche durchführt, behält die Markup-Erweiterung DynamicResource
eine Verknüpfung mit dem Wörterbuchschlüssel bei. Wenn also der mit dem Schlüssel verbundene Wörterbucheintrag ersetzt wird, wird die Änderung auf das visuelle Element angewendet. Dadurch können Laufzeitressourcenänderungen in einer Anwendung vorgenommen werden. Weitere Informationen zu Markuperweiterungen finden Sie unter XAML-Markuperweiterungen.
Das folgende XAML-Beispiel zeigt, wie Ressourcen verbraucht werden, und definiert auch zusätzliche Ressourcen in einer StackLayout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.HomePage"
Title="Home Page">
<StackLayout Margin="{StaticResource PageMargin}">
<StackLayout.Resources>
<!-- Implicit style -->
<Style TargetType="Button">
<Setter Property="FontSize" Value="Medium" />
<Setter Property="BackgroundColor" Value="#1976D2" />
<Setter Property="TextColor" Value="White" />
<Setter Property="CornerRadius" Value="5" />
</Style>
</StackLayout.Resources>
<Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries." />
<Button Text="Navigate"
Clicked="OnNavigateButtonClicked" />
</StackLayout>
</ContentPage>
In diesem Beispiel verwendet das ContentPage
Objekt die implizite Formatvorlage, die im Ressourcenverzeichnis auf Anwendungsebene definiert ist. Das StackLayout
Objekt verwendet die PageMargin
im Ressourcenverzeichnis auf Anwendungsebene definierte Ressource, während das Button
Objekt den im StackLayout
Ressourcenwörterbuch definierten impliziten Stil verwendet. Dies ergibt die in den folgenden Screenshots gezeigte Darstellung:
Wichtig
Ressourcen, die für eine einzelne Seite spezifisch sind, sollten nicht in ein Ressourcenverzeichnis auf Anwendungsebene einbezogen werden, da ressourcen dann beim Starten der Anwendung analysiert werden, statt wenn eine Seite erforderlich ist. Weitere Informationen finden Sie unter Verringern der Größe des Anwendungsressourcenwörterbuchs.
Suchverhalten von Ressourcen
Der folgende Nachschlagevorgang tritt auf, wenn eine Ressource mit der StaticResource
oder DynamicResource
Markup-Erweiterung referenziert wird:
- Die Suche prüft den angeforderten Schlüssel im Ressourcenverzeichnis, der durch das Element definiert wird, welches die Eigenschaft festlegt: Wenn der angeforderte Schlüssel gefunden wird, wird der Wert zurückgegeben, und der Nachschlagevorgang wird beendet.
- Wenn keine Übereinstimmung gefunden wird, durchsucht der Nachschlagevorgang die visuelle Struktur nach oben, und überprüft das Ressourcenverzeichnis jedes übergeordneten Elements. Wenn der angeforderte Schlüssel gefunden wird, wird der Wert zurückgegeben, und der Nachschlagevorgang wird beendet. Andernfalls wird dieser Vorgang fortgesetzt, bis das Basiselelement erreicht ist.
- Wenn eine Übereinstimmung nicht im Basiselement gefunden wird, wird das Ressourcenverzeichnis auf Anwendungsebene untersucht.
- Wenn eine Übereinstimmung immer noch nicht gefunden wird, wird ein
XamlParseException
Fehler ausgelöst.
Wenn also der XAML-Parser auf eine StaticResource
oder DynamicResource
Markup-Erweiterung stößt, sucht er nach einem passenden Schlüssel, indem er den visuellen Baum nach oben durchläuft und die erste gefundene Übereinstimmung verwendet. Wenn diese Suche auf der Seite endet und der Schlüssel noch nicht gefunden wurde, durchsucht der XAML Parser das ResourceDictionary
angefügt an das App
Objekt. Wenn der Schlüssel immer noch nicht gefunden wird, wird eine Ausnahme ausgelöst.
Außerkraftsetzung von Ressourcen
Wenn Ressourcen Schlüssel gemeinsam nutzen, haben Ressourcen, die in der visuellen Struktur niedriger definiert sind, Vorrang vor den darüber definierten Ressourcen. Wenn beispielsweise eine AppBackgroundColor
Ressource auf der Anwendungsebene auf AliceBlue
gesetzt wird, wird sie von einer AppBackgroundColor
Ressource auf Seitenebene, die auf Teal
gesetzt ist, überschrieben. Ebenso wird eine Ressourcen auf Seitenebene AppBackgroundColor
von einer Ressource auf Steuerelementebene AppBackgroundColor
überschrieben.
Eigenständige Ressourcenverzeichnisse
Eine von dieser ResourceDictionary
abgeleitete Klasse kann sich auch in einer eigenständigen XAML-Datei befinden. Die XAML-Datei kann dann zwischen Anwendungen freigegeben werden.
Um eine solche Datei zu erstellen, fügen Sie dem Projekt ein neues Inhaltsansichts - oder Inhaltsseitenelement hinzu (jedoch keine Inhaltsansicht oder Inhaltsseite mit nur einer C#-Datei). Löschen Sie die CodeBehind-Datei, und ändern Sie in der XAML-Datei den Namen der Basisklasse von ContentView
oder ContentPage
in ResourceDictionary
. Entfernen Sie außerdem das x:Class
Attribut aus dem Stammtag der Datei.
Das folgende XAML-Beispiel zeigt einen ResourceDictionary
Namen namens "MyResourceDictionary.xaml":
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<DataTemplate x:Key="PersonDataTemplate">
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"
TextColor="{StaticResource NormalTextColor}"
FontAttributes="Bold" />
<Label Grid.Column="1"
Text="{Binding Age}"
TextColor="{StaticResource NormalTextColor}" />
<Label Grid.Column="2"
Text="{Binding Location}"
TextColor="{StaticResource NormalTextColor}"
HorizontalTextAlignment="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
In diesem Beispiel enthält die ResourceDictionary
eine einzelne Ressource, bei der es sich um ein Objekt vom Typ DataTemplate
handelt. MyResourceDictionary.xaml kann genutzt werden, indem es in ein anderes Ressourcenwörterbuch zusammengeführt wird.
Standardmäßig entfernt der Linker eigenständige XAML-Dateien aus Releasebuilds, wenn das Linkerverhalten so festgelegt ist, dass alle Assemblys verknüpft werden. So stellen Sie sicher, dass eigenständige XAML-Dateien in einem Releasebuild verbleiben:
Fügen Sie der Assembly ein benutzerdefiniertes
Preserve
Attribut hinzu, das die eigenständigen XAML-Dateien enthält. Weitere Informationen finden Sie unter Beibehalten von Code.Legen Sie das
Preserve
Attribut auf Assemblyebene fest:[assembly:Preserve(AllMembers = true)]
Weitere Informationen zum Verknüpfen finden Sie unter "Verknüpfen von Xamarin.iOS-Apps und Verknüpfen unter Android".
Zusammengeführte Ressourcenwörterbücher
Zusammengeführte Ressourcenwörterbücher kombinieren ein oder ResourceDictionary
mehrere Objekte in einem anderen ResourceDictionary
.
Lokale Ressourcenwörterbücher zusammenführen
Eine lokale ResourceDictionary
Datei kann in eine andere ResourceDictionary
Datei zusammengeführt werden, indem ein ResourceDictionary
Objekt erstellt wird, dessen Source
Eigenschaft auf den Dateinamen der XAML Datei mit den Ressourcen gesetzt wird:
<ContentPage ...>
<ContentPage.Resources>
<!-- Add more resources here -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
<!-- Add more resources here -->
</ContentPage.Resources>
...
</ContentPage>
Diese Syntax instanziiert die MyResourceDictionary
Klasse nicht. Stattdessen verweist sie auf die XAML Datei. Aus diesem Grund ist beim Festlegen der Source
Eigenschaft keine CodeBehind-Datei erforderlich, und das x:Class
Attribut kann aus dem Stammtag der MyResourceDictionary.xaml Datei entfernt werden.
Wichtig
Die Source
Eigenschaft kann nur aus XAML festgelegt werden.
Zusammenführen von Ressourcenwörterbüchern aus anderen Baugruppen
Ein ResourceDictionary
kann auch mit einem anderen ResourceDictionary
verschmolzen werden, indem es in die MergedDictionaries
Eigenschaft des ResourceDictionary
eingefügt wird. Mit dieser Technik können Ressourcenwörterbücher zusammengeführt werden, unabhängig von der Baugruppe, in der sie sich befinden. Für das ResourceDictionary
Zusammenführen von Ressourcenwörterbüchern aus externen Assemblys muss eine Buildaktion auf "EmbeddedResource" festgelegt sein, eine CodeBehind-Datei vorhanden sein und das x:Class
Attribut im Stammtag der Datei definiert werden.
Warnung
Die ResourceDictionary
-Klasse definiert ebenfalls eine MergedWith
-Eigenschaft. Diese Eigenschaft ist jedoch veraltet und sollte nicht mehr verwendet werden.
Das folgende Codebeispiel zeigt, wie zwei Ressourcenwörterbücher der MergedDictionaries
Sammlung einer Seitenebene ResourceDictionary
hinzugefügt werden:
<ContentPage ...
xmlns:local="clr-namespace:ResourceDictionaryDemo"
xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
<ContentPage.Resources>
<ResourceDictionary>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<local:MyResourceDictionary />
<theme:LightTheme />
<!-- Add more resource dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Add more resources here -->
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
In diesem Beispiel werden ein Ressourcenwörterbuch aus derselben Baugruppe und ein Ressourcenwörterbuch aus einer externen Baugruppe in das Ressourcenverzeichnis auf Seitenebene zusammengeführt. Darüber hinaus können Sie auch andere ResourceDictionary
Objekte innerhalb der MergedDictionaries
Eigenschaftselementtags und andere Ressourcen außerhalb dieser Tags hinzufügen.
Wichtig
Es kann nur ein MergedDictionaries
Eigenschaftselement-Tag geben in einem ResourceDictionary
, aber Sie können so viele ResourceDictionary
-Objekte darin unterbringen wie nötig.
Wenn zusammengeführte ResourceDictionary
Ressourcen identische x:Key
Attributwerte gemeinsam nutzen, Xamarin.Forms wird die folgende Ressourcenrangfolge verwendet:
- Die lokalen Ressourcen im Ressourcenwörterbuch.
- Die in den Ressourcen-Wörterbüchern enthaltenen Ressourcen, die über die
MergedDictionaries
Sammlung zusammengeführt wurden, sind in umgekehrter Reihenfolge in derMergedDictionaries
Eigenschaft aufgeführt.
Hinweis
Das Durchsuchen von Ressourcenwörterbüchern kann eine rechenintensive Aufgabe sein, wenn eine Anwendung mehrere, große Ressourcenwörterbücher enthält. Um unnötige Suche zu vermeiden, sollten Sie daher sicherstellen, dass jede Seite in einer Anwendung nur Ressourcenwörterbücher verwendet, die für die Seite geeignet sind.
Verwandte Links
- XAML-Markuperweiterungen
- Xamarin.Forms-Formatvorlagen
- Verknüpfen von Xamarin.iOS-Apps
- Linking on Android (Verknüpfung unter Android)
- ResourceDictionary-API
Zugehörige Videos
Auf Channel 9 und auf YouTube finden Sie weitere Videos zu Xamarin.