XAML-Markuperweiterungen
Ein Großteil Ihrer XAML-Definition wird zur Kompilierzeit geklärt sein. Häufig wissen Sie, wo Elemente positioniert werden sollten, welche Farben und Schriftarten verwendet werden und welchen Literal werten Eigenschaften zugewiesen werden sollten.
Mitunter müssen Sie einen Eigenschaftswert auf einen Wert festlegen, der zur Kompilierzeit nicht bestimmt werden kann. Diese Werte werden erst bekannt, wenn das Programm ausgeführt wird. In diesen Situationen können Sie ein Objekt erstellen, das zur Laufzeit einen Wert für XAML bereitstellt. XAML unterstützt zu diesem Zweck Markuperweiterungen.
In dieser Lerneinheit erfahren Sie, wie Sie Markuperweiterungen erstellen und verwenden.
Was ist eine Markuperweiterung?
Eine Markuperweiterung ist eine Klasse, die Sie in XAML für den Zugriff auf Laufzeitwerte benötigen. Angenommen, Sie haben in der XAML-Benutzeroberfläche viele Bezeichnungen definiert und möchten die Eigenschaft FontSize
in der gesamten App auf ein und denselben Wert festlegen, um sicherzustellen, dass der Stil aller Bezeichnungen konsistent ist. Sie können die Eigenschaft FontSize
mithilfe von XAML festlegen, wie im folgenden Beispiel gezeigt:
<Label Text="Hello, World!"
Grid.Row="0"
SemanticProperties.HeadingLevel="Level1"
FontSize="28"
HorizontalOptions="CenterAndExpand"/>
Sie können diese Einstellung für jede Bezeichnung wiederholen, aber was ist, wenn Sie diesen Wert später ändern möchten? Sie müssen nach jeder Instanz dieser Eigenschaft suchen und die Änderung vornehmen. Angenommen, Sie wissen nicht, welchen Wert Sie verwenden sollten. Möglicherweise wird er zur Laufzeit auf der Grundlage von Geräteausrichtung, Bildschirmauflösung oder anderen Faktoren berechnet. In diesen Fällen benötigen Sie etwas Anspruchsvolleres als ein hartcodiertes Literal. Hier ist eine Markuperweiterung nützlich. Markuperweiterungen ermöglichen Flexibilität, wie Sie einen Wert abrufen, der in XAML verwendet wird.
Erstellen einer Markuperweiterung
Eine Markuperweiterung ist eine Klasse, die die Schnittstelle Microsoft.Maui.Controls.Xaml.IMarkupExtension implementiert. Diese Schnittstelle definiert eine Methode namens ProvideValue
mit der folgenden Signatur:
public object ProvideValue(IServiceProvider serviceProvider)
{
...
}
Zweck dieser Methode ist die Bereitstellung eines Werts für das XAML-Markup. Beachten Sie, dass der Rückgabetyp object
lautet. Der Wert kann also einen beliebigen Typ aufweisen, solange er für die Umgebung geeignet ist, in der er verwendet wird. Beispielsweise sollte der Rückgabetyp in einer Markuperweiterung, die einen Schriftgrad berechnet und zurückgibt, double
lauten.
Der Parameter serviceProvider
enthält Kontextinformationen dazu, an welchen Stellen im XAML-Code die Markuperweiterung verwendet wird. Er gibt unter anderem das Steuerelement an, auf das die Erweiterung angewendet wird.
Sie können die Markuperweiterung für die Eigenschaft FontSize
einfach halten. Im folgenden Beispiel macht die Klasse MainPage
ein double
-Feld mit dem Namen MyFontSize
verfügbar. Die Klasse GlobalFontSizeExtension
implementiert die Schnittstelle IMarkupExtension
, und die Methode ProvideValue
gibt den Wert der Variable MyFontSize
zurück:
namespace MyMauiApp;
public partial class MainPage : ContentPage
{
public const double MyFontSize = 28;
public MainPage()
{
InitializeComponent();
...
}
...
}
public class GlobalFontSizeExtension : IMarkupExtension
{
public object ProvideValue(IServiceProvider serviceProvider)
{
return MainPage.MyFontSize;
}
}
Hinweis
Das Feld MyFontSize
muss ein static
-Element der Klasse MainPage
sein, damit in der Methode ProvideValue
entsprechend darauf verwiesen werden kann. Es hat sich bewährt, dass die Variable in diesem Fall auch eine Konstante ist. Ein const
-Wert ist static
.
Die Methode ProvideValue
kann je nach Ausrichtung und Formfaktor des Geräts auch Anpassungen am zurückgegebenen Wert vornehmen.
Anwenden der Markuperweiterung auf ein Steuerelement in XAML
Wenn Sie die Markuperweiterung in Ihrem XAML-Code verwenden möchten, fügen Sie den Namespace, der die Klasse GlobalFontSizeExtension
enthält, der Liste der Namespaces im Tag ContentPage
hinzu. Im folgenden Beispiel erhält dieser Namespace den Alias mycode:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mycode="clr-namespace:MyMauiApp"
x:Class="MyMauiApp.MainPage">
Sie können die Markuperweiterung verwenden, um die Eigenschaft FontSize
auf diese Weise festzulegen. Beachten Sie, dass eine Markuperweiterung gemäß Konvention das Suffix Extension im Namen enthält. XAML erkennt dieses Suffix, und Sie müssen es nicht einschließen, wenn Sie die Erweiterung über Ihren XAML-Code aufrufen. Im folgenden Beispiel wird auf die Klasse GlobalFontSizeExtension
einfach als GlobalFontSize
verwiesen:
<Label Text="Hello, World!"
Grid.Row="0"
SemanticProperties.HeadingLevel="Level1"
FontSize="{mycode:GlobalFontSize}"
HorizontalOptions="CenterAndExpand"/>
Sie können dieselbe Markuperweiterung im gesamten XAML-Code für jedes Steuerelement anwenden, für das der Schriftgrad angegeben werden muss. Wenn Sie den Schriftgrad später ändern möchten, müssen Sie nur die Definition der Variablen MyFontSize
in der Klasse MainPage
ändern.
Die StaticExtension-Klasse
So nützlich die Markuperweiterung GlobalFontSize
auch ist – es ist unwahrscheinlich, dass Sie jemals eine solche Erweiterung erstellen. Der Grund dafür ist einfach. .NET MAUI bietet bereits eine allgemeinere Erweiterung, mit der Sie auf beliebige statische Werte in Ihrem Code verweisen können. Diese Erweiterung heißt StaticExtension
oder kurz Static
. Der folgende Code zeigt die Grundstruktur dieser Erweiterungsklasse:
[ContentProperty ("Member")]
public class StaticExtension : IMarkupExtension
{
public string Member {get; set;}
public object ProvideValue (IServiceProvider serviceProvider)
{
...
}
}
Hinweis
Benutzerdefinierte Markuperweiterungen sind dafür konzipiert, dass Sie nicht nur einfache statische Fälle, sondern auch komplexere Situationen verarbeiten können. Ein Beispiel: Möglicherweise müssen Sie den Schriftgrad basierend auf dem Geräteformfaktor dynamisch ändern.
Wenn Sie diese Klasse in Ihrem XAML-Code verwenden, geben Sie den Namen der statischen Variablen an, auf die Sie in der Eigenschaft Member
verweisen möchten. Die Methode ProvideValue
gibt dann den Wert in dieser Variablen zurück. Das folgende Beispiel veranschaulicht ihre Verwendung:
<Label Text="Hello, World!"
Grid.Row="0"
SemanticProperties.HeadingLevel="Level1"
FontSize="{x:Static Member=mycode:MainPage.MyFontSize}"
HorizontalOptions="CenterAndExpand"/>
.NET MAUI stellt eine Reihe weiterer Markuperweiterungsklassen bereit, die Sie für Szenarien wie Datenbindung, das Verweisen auf dynamische Ressourcen und Stile sowie die Verarbeitung von Datenarrays verwenden können.