Teilen über


Design einer Xamarin.Forms Anwendung

Xamarin.Forms Anwendungen können dynamisch auf Formatänderungen zur Laufzeit reagieren, indem sie die DynamicResource Markuperweiterung verwenden. Diese Markuperweiterung ist der StaticResource-Markuperweiterung insofern ähnlich, als beide einen Wörterbuchschlüssel verwenden, um einen Wert aus einem ResourceDictionary zu extrahieren. Während die StaticResource-Markuperweiterung eine einzelne Wörterbuchsuche durchführt, behält die DynamicResource-Markuperweiterung einen Link zum Wörterbuchschlüssel bei. Wenn also der dem Schlüssel zugeordnete Wert ersetzt wird, wird die Änderung auf das VisualElement angewendet. Dadurch können Laufzeitdesigns in Xamarin.Forms Anwendungen implementiert werden.

Der Prozess für die Implementierung des Laufzeitdesigns in einer Xamarin.Forms Anwendung lautet wie folgt:

  1. Definieren Sie die Ressourcen für jedes Design in einem ResourceDictionary.
  2. Verwenden Sie Designressourcen in der Anwendung mithilfe der DynamicResource Markuperweiterung.
  3. Legen Sie ein Standarddesign in der App.xaml-Datei der Anwendung fest.
  4. Fügen Sie Code hinzu, um ein Design zur Laufzeit zu laden.

Wichtig

Verwenden Sie die StaticResource-Markuperweiterung, wenn Sie das App-Design nicht zur Laufzeit ändern müssen.

Die folgenden Screenshots zeigen Designseiten mit der iOS-Anwendung mit einem hellen Design und der Android-Anwendung mit einem dunklen Design:

Screenshot der Hauptseite einer Design-App unter iOS und AndroidScreenshot der Detailseite einer Design-App unter iOS und Android

Hinweis

Das Ändern eines Designs zur Laufzeit erfordert die Verwendung von XAML-Formatvorlagen und ist derzeit nicht mit CSS möglich.

Definieren von Designs

Ein Design wird als eine Sammlung von Ressourcenobjekten definiert, die in einem ResourceDictionary gespeichert sind.

Das folgende Beispiel zeigt die LightTheme Beispielanwendung:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.LightTheme">
    <Color x:Key="PageBackgroundColor">White</Color>
    <Color x:Key="NavigationBarColor">WhiteSmoke</Color>
    <Color x:Key="PrimaryColor">WhiteSmoke</Color>
    <Color x:Key="SecondaryColor">Black</Color>
    <Color x:Key="PrimaryTextColor">Black</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">Gray</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

Das folgende Beispiel zeigt die DarkTheme Beispielanwendung:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.DarkTheme">
    <Color x:Key="PageBackgroundColor">Black</Color>
    <Color x:Key="NavigationBarColor">Teal</Color>
    <Color x:Key="PrimaryColor">Teal</Color>
    <Color x:Key="SecondaryColor">White</Color>
    <Color x:Key="PrimaryTextColor">White</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">WhiteSmoke</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

Jedes ResourceDictionary enthält Color-Ressourcen, die ihre jeweiligen Designs definieren, wobei jedes ResourceDictionary identische Schlüsselwerte verwendet. Weitere Informationen zu Ressourcenverzeichnissen finden Sie unter Ressourcenverzeichnisse.

Wichtig

Für jedes ResourceDictionary, das die InitializeComponent-Methode aufruft, ist eine CodeBehind-Datei erforderlich. Nur so kann zur Laufzeit ein CLR-Objekt erstellt werden, das das ausgewählte Design repräsentiert.

Festlegen eines Standarddesigns

Für eine Anwendung ist ein Standarddesign erforderlich, sodass Steuerelemente Werte für die ressourcen aufweisen, die sie verbrauchen. Ein Standarddesign kann festgelegt werden, indem das Design ResourceDictionary in der anwendungsebene ResourceDictionary zusammengeführt wird, die in "App.xaml" definiert ist:

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>
        <ResourceDictionary Source="Themes/LightTheme.xaml" />
    </Application.Resources>
</Application>

Weitere Informationen zum Zusammenführen von Ressourcenverzeichnissen finden Sie unter Zusammengeführte Ressourcenverzeichnisse.

Verwenden von Designressourcen

Wenn eine Anwendung eine Ressource nutzen möchte, die in einem ResourceDictionary Design gespeichert ist, das ein Design darstellt, sollte dies mit der DynamicResource Markuperweiterung ausgeführt werden. Dadurch wird sichergestellt, dass bei der Auswahl eines anderen Designs zur Laufzeit die Werte des neuen Designs verwendet werden.

Das folgende Beispiel zeigt drei Formatvorlagen aus der Beispielanwendung, die auf Label Objekte angewendet werden können:

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>

        <Style x:Key="LargeLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource SecondaryTextColor}" />
            <Setter Property="FontSize"
                    Value="30" />
        </Style>

        <Style x:Key="MediumLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource PrimaryTextColor}" />
            <Setter Property="FontSize"
                    Value="25" />
        </Style>

        <Style x:Key="SmallLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource TertiaryTextColor}" />
            <Setter Property="FontSize"
                    Value="15" />
        </Style>

    </Application.Resources>
</Application>

Diese Stile werden im Ressourcenverzeichnis auf Anwendungsebene definiert, sodass sie von mehreren Seiten genutzt werden können. Jede Formatvorlage verwendet Designressourcen mit der DynamicResource-Markuperweiterung.

Diese Formatvorlagen werden dann von Seiten verwendet:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ThemingDemo"
             x:Class="ThemingDemo.UserSummaryPage"
             Title="User Summary"
             BackgroundColor="{DynamicResource PageBackgroundColor}">
    ...
    <ScrollView>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200" />
                <RowDefinition Height="120" />
                <RowDefinition Height="70" />
            </Grid.RowDefinitions>
            <Grid BackgroundColor="{DynamicResource PrimaryColor}">
                <Label Text="Face-Palm Monkey"
                       VerticalOptions="Center"
                       Margin="15"
                       Style="{StaticResource MediumLabelStyle}" />
                ...
            </Grid>
            <StackLayout Grid.Row="1"
                         Margin="10">
                <Label Text="This monkey reacts appropriately to ridiculous assertions and actions."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Cynical but not unfriendly."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Seven varieties of grimaces."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Doesn't laugh at your jokes."
                       Style="{StaticResource SmallLabelStyle}" />
            </StackLayout>
            ...
        </Grid>
    </ScrollView>
</ContentPage>

Wenn eine Designressource direkt verwendet wird, sollte dies mit der DynamicResource-Markuperweiterung geschehen. Wenn jedoch eine Formatvorlage verwendet wird, die die DynamicResource-Markuperweiterung verwendet, sollte dies mit der StaticResource-Markuperweiterung geschehen.

Weitere Informationen zum Formatieren finden Sie unter Formatieren Xamarin.Forms von Apps mit XAML-Formatvorlagen. Weitere Informationen zur DynamicResource Markuperweiterung finden Sie unter Dynamische Formatvorlagen in Xamarin.Forms.

Laden eines Designs während der Laufzeit

Wenn ein Design zur Laufzeit ausgewählt wird, sollte die Anwendung Folgendes ausführen:

  1. Entfernen Sie das aktuelle Design aus der Anwendung. Dies wird durch Löschen der MergedDictionaries Eigenschaft der Anwendungsebene ResourceDictionaryerreicht.
  2. Das ausgewählte Design laden. Dies wird durch Hinzufügen einer Instanz des ausgewählten Designs zur MergedDictionaries Eigenschaft der Anwendungsebene ResourceDictionaryerreicht.

Alle VisualElement-Objekte, die Eigenschaften mit der DynamicResource-Markuperweiterung festlegen, wenden dann die neuen Designwerte an. Dies geschieht, da die DynamicResource-Markuperweiterung einen Link zu Verzeichnisschlüsseln enthält. Wenn die mit Schlüsseln verknüpften Werte ersetzt werden, werden die Änderungen daher auf die VisualElement-Objekte angewendet.

In der Beispielanwendung wird ein Design über eine modale Seite ausgewählt, die einen Picker enthält. Der folgende Code zeigt die OnPickerSelectionChanged-Methode, die ausgeführt wird, wenn sich das ausgewählte Design ändert:

void OnPickerSelectionChanged(object sender, EventArgs e)
{
    Picker picker = sender as Picker;
    Theme theme = (Theme)picker.SelectedItem;

    ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
    if (mergedDictionaries != null)
    {
        mergedDictionaries.Clear();

        switch (theme)
        {
            case Theme.Dark:
                mergedDictionaries.Add(new DarkTheme());
                break;
            case Theme.Light:
            default:
                mergedDictionaries.Add(new LightTheme());
                break;
        }
    }
}