Verwenden von XAML-Markuperweiterungen
XAML-Markuperweiterungen für .NET Multi-Platform App UI (.NET MAUI) verbessern die Leistungsfähigkeit und Flexibilität von XAML, indem Elementattribute aus einer Vielzahl von Quellen festgelegt werden können.
Beispielsweise legen Sie in der Regel die Color
-Eigenschaft von BoxView wie folgt fest:
<BoxView Color="Blue" />
Sie können es jedoch lieber vorziehen, das attribut Color
aus einem in einem Ressourcenwörterbuch gespeicherten Wert oder dem Wert einer statischen Eigenschaft einer klasse festzulegen, die Sie erstellt haben, oder aus einer Eigenschaft vom Typ Color eines anderen Elements auf der Seite oder aus separaten Farbton-, Sättigungs- und Leuchtdichtewerten erstellt. Alle diese Optionen sind mithilfe von XAML-Markuperweiterungen möglich.
Eine Markuperweiterung ist eine andere Möglichkeit, ein Attribut eines Elements auszudrücken. .NET MAUI XAML-Markuperweiterungen sind in der Regel durch einen Attributwert identifizierbar, der in geschweifte Klammern eingeschlossen ist:
<BoxView Color="{StaticResource themeColor}" />
Jeder Attributwert in geschweiften Klammern ist immer eine XAML-Markup-Erweiterung. XAML-Markuperweiterungen können jedoch auch ohne die Verwendung von geschweiften Klammern referenziert werden.
Anmerkung
Mehrere XAML-Markuperweiterungen sind Teil der XAML 2009-Spezifikation. Diese werden in XAML-Dateien mit dem üblichen x
Namespacepräfix angezeigt und werden häufig mit diesem Präfix bezeichnet.
Zusätzlich zu den in diesem Artikel erläuterten Markuperweiterungen sind die folgenden Markuperweiterungen in .NET MAUI enthalten und in anderen Artikeln erläutert:
-
AppThemeBinding
– gibt eine Ressource an, die basierend auf dem aktuellen Systemdesign verbraucht werden soll. Weitere Informationen finden Sie unter AppThemeBinding-Markuperweiterung. -
Binding
– stellt eine Verknüpfung zwischen Eigenschaften von zwei Objekten her. Weitere Informationen finden Sie unter Datenbindung. -
DynamicResource
– reagiert auf Änderungen an Objekten in einem Ressourcenwörterbuch. Weitere Informationen finden Sie unter Dynamischen Formatvorlagen. -
FontImage
- Zeigt ein Schriftartsymbol in jeder Ansicht an, die eine ImageSourceanzeigen kann. Für weitere Informationen siehe Laden eines Font-Icons. -
OnIdiom
– Passt die Ui-Darstellung basierend auf dem Idiom des Geräts an, auf dem die Anwendung ausgeführt wird. Weitere Informationen finden Sie unter Anpassen der Ui-Darstellung basierend auf dem Gerätediom. -
OnPlatform
– Passt die Darstellung der Benutzeroberfläche auf Plattformbasis an. Weitere Informationen finden Sie unter Anpassen der UI-Darstellung basierend auf der Plattform. -
RelativeSource
– legt die Bindungsquelle relativ zur Position des Bindungsziels fest. Weitere Informationen finden Sie unter relative Bindungen. -
StaticResource
– verweist auf Objekte aus einem Ressourcenwörterbuch. Weitere Informationen finden Sie unter Ressourcenwörterbücher. -
TemplateBinding
– Führt datenbindung aus einer Steuerelementvorlage aus. Weitere Informationen finden Sie unter Steuerelementvorlagen.
x:Static markup extension
Die x:Static
Markuperweiterung wird von der StaticExtension Klasse unterstützt. Die Klasse hat eine einzelne Eigenschaft namens Member
vom Typ string
, die Sie auf den Namen einer öffentlichen Konstanten, statischen Eigenschaft, statischem Feld oder Enumerationsmitglied festlegen.
Eine Möglichkeit, x:Static
zu verwenden, besteht darin, zuerst eine Klasse mit einigen Konstanten oder statischen Variablen zu definieren, z. B. diese AppConstants
-Klasse:
static class AppConstants
{
public static double NormalFontSize = 18;
}
Der folgende XAML-Code veranschaulicht den ausführlichsten Ansatz zur Instanziierung der Klasse StaticExtension zwischen Label.FontSize
Eigenschaftselement-Tags:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.StaticDemoPage"
Title="x:Static Demo">
<StackLayout Margin="10, 0">
<Label Text="Label No. 1">
<Label.FontSize>
<x:StaticExtension Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
···
</StackLayout>
</ContentPage>
Der XAML-Parser ermöglicht außerdem, dass die StaticExtension-Klasse wie x:Static
abgekürzt wird:
<Label Text="Label No. 2">
<Label.FontSize>
<x:Static Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
Diese Syntax kann noch weiter vereinfacht werden, indem die StaticExtension-Klasse und die Mitgliedereinstellungen in geschweifte Klammern gesetzt werden. Der resultierende Ausdruck wird direkt auf das attribut FontSize
festgelegt:
<Label Text="Label No. 3"
FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />
In diesem Beispiel gibt es keine Anführungszeichen innerhalb der geschweiften Klammern. Die Member
Eigenschaft von StaticExtension ist kein XML-Attribut mehr. Stattdessen ist es Teil des Ausdrucks für die Markup-Erweiterung.
Genauso wie Sie x:StaticExtension
kürzen können, wenn Sie es als Objektelement zu x:Static
machen, können Sie es auch im Ausdruck in geschweiften Klammern kürzen.
<Label Text="Label No. 4"
FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />
Die StaticExtension Klasse verfügt über ein ContentProperty
Attribut, das auf die Eigenschaft Member
verweist, die diese Eigenschaft als Standardinhaltseigenschaft der Klasse kennzeichnet. Für XAML-Markuperweiterungen, die mit geschweiften Klammern ausgedrückt werden, können Sie den Member=
Teil des Ausdrucks beseitigen:
<Label Text="Label No. 5"
FontSize="{x:Static local:AppConstants.NormalFontSize}" />
Dies ist die häufigste Form der x:Static
Markup-Erweiterung.
Das Stammtag des XAML-Beispiels enthält auch eine XML-Namespacedeklaration für den .NET-System
-Namespace. Dadurch kann die Schriftgröße Label für das statische Feld Math.PI
festgelegt werden. Dies führt zu eher kleinem Text, sodass die eigenschaft Scale
auf Math.E
festgelegt ist:
<Label Text="π × E sized text"
FontSize="{x:Static sys:Math.PI}"
Scale="{x:Static sys:Math.E}"
HorizontalOptions="Center" />
Der folgende Screenshot zeigt die XAML-Ausgabe:
x:Reference-Markup-Erweiterung
Die x:Reference
Markuperweiterung wird von der ReferenceExtension Klasse unterstützt. Die Klasse verfügt über eine einzelne Eigenschaft mit dem Namen Name
vom Typ string
, die Sie auf den Namen eines Elements auf der Seite festlegen, die mit x:Name
einen Namen erhalten hat. Diese Name
-Eigenschaft ist die Inhaltseigenschaft von ReferenceExtension, sodass Name=
nicht erforderlich ist, wenn x:Reference
in geschweiften Klammern angezeigt wird. Die x:Reference
Markuperweiterung wird ausschließlich mit Datenbindungen verwendet. Weitere Informationen zu Datenbindungen finden Sie unter Datenbindung.
Das folgende XAML-Beispiel zeigt zwei Verwendungen von x:Reference
mit Datenbindungen, der erste, an der sie zum Festlegen der Source
-Eigenschaft des Binding
-Objekts verwendet wird, und die zweite, in der sie zum Festlegen der BindingContext
-Eigenschaft für zwei Datenbindungen verwendet wird:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ReferenceDemoPage"
x:Name="page"
Title="x:Reference Demo">
<StackLayout Margin="10, 0">
<Label x:DataType="ContentPage"
Text="{Binding Source={x:Reference page},
StringFormat='The type of this page is {0}'}"
FontSize="18"
VerticalOptions="Center"
HorizontalTextAlignment="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
<Label x:DataType="Slider"
BindingContext="{x:Reference slider}"
Text="{Binding Value, StringFormat='{0:F0}° rotation'}"
Rotation="{Binding Value}"
FontSize="24"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
In diesem Beispiel verwenden beide x:Reference
Ausdrücke die abgekürzte Version des ReferenceExtension Klassennamens und entfernen den Name=
Teil des Ausdrucks. Im ersten Beispiel ist die x:Reference
Markuperweiterung in die Binding
Markuperweiterung eingebettet, und die eigenschaften Source
und StringFormat
werden durch Kommas getrennt.
Der folgende Screenshot zeigt die XAML-Ausgabe:
x:Type-Markuperweiterung
Die x:Type
Markuperweiterung ist das XAML-Äquivalent des C#-schlüsselworts typeof
. Es wird von der TypeExtension-Klasse unterstützt, die eine Eigenschaft mit dem Namen TypeName
vom Typ string
definiert, die auf einen Klassen- oder Strukturnamen festgelegt werden soll. Die x:Type
Markuperweiterung gibt das Type
Objekt dieser Klasse oder Struktur zurück.
TypeName
ist die Inhaltseigenschaft von TypeExtension, daher ist TypeName=
nicht erforderlich, wenn x:Type
mit geschweiften Klammern angezeigt wird.
Die x:Type
Markuperweiterung wird häufig mit der x:Array
Markuperweiterung verwendet. Weitere Informationen finden Sie unter x:Array-Markuperweiterung.
Im folgenden XAML-Beispiel wird die Verwendung der x:Type
-Markup-Erweiterung zum Instanziieren von .NET MAUI-Objekten veranschaulicht und sie zu StackLayouthinzugefügt. Der XAML-Code besteht aus drei Button Elementen, deren Command
Eigenschaften auf ein Binding
und die CommandParameter
Eigenschaften auf Typen von drei .NET MAUI-Ansichten festgelegt sind:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.TypeDemoPage"
Title="x:Type Demo"
x:DataType="local:TypeDemoPage">
<StackLayout x:Name="stackLayout"
Padding="10, 0">
<Button Text="Create a Slider"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Switch}" />
</StackLayout>
</ContentPage>
Die CodeBehind-Datei definiert und initialisiert die CreateCommand
-Eigenschaft:
public partial class TypeDemoPage : ContentPage
{
public ICommand CreateCommand { get; private set; }
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.Center;
stackLayout.Add(view);
});
BindingContext = this;
}
}
Wenn ein Button gedrückt wird, wird eine neue Instanz des arguments CommandParameter
erstellt und dem StackLayouthinzugefügt. Die drei Button Objekte teilen sich dann die Seite mit dynamisch erzeugten Ansichten:
Generische Typen können mit der x:Type
Markuperweiterung angegeben werden, indem die generische Einschränkung als präfixiertes Zeichenfolgenargument in Klammern angegeben wird:
<x:Array Type="{x:Type local:MyType(local:MyObject)}">
...
</x:Array>
Mehrere Typargumente können als präfixierte Zeichenfolgenargumente angegeben werden, die durch ein Komma getrennt werden:
<x:Array Type="{x:Type local:MyType(local:MyObject,x:Boolean)}">
...
</x:Array>
Weitere Informationen zu Generischen in XAML finden Sie unter Generics.
x:Array-Markup-Erweiterung
Mit der x:Array
Markuperweiterung können Sie ein Array im Markup definieren. Sie wird von der ArrayExtension-Klasse unterstützt, die zwei Eigenschaften definiert:
-
Type
vom TypType
, der den Typ der Elemente im Array angibt. Diese Eigenschaft sollte auf einex:Type
-Markup-Erweiterung festgelegt werden. -
Items
vom TypIList
, bei dem es sich um eine Sammlung der Elemente selbst handelt. Dies ist die Inhaltseigenschaft von ArrayExtension.
Die x:Array
-Markuperweiterung selbst wird nie in geschweiften Klammern angezeigt. Stattdessen trennen x:Array
Start- und Endtags die Liste der Elemente.
Im folgenden XAML-Beispiel wird gezeigt, wie Sie x:Array
verwenden, um einem ListView Elemente hinzuzufügen, indem Sie die eigenschaft ItemsSource
auf ein Array festlegen:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ArrayDemoPage"
Title="x:Array Demo Page">
<ListView Margin="10">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate x:DataType="Color">
<ViewCell>
<BoxView Color="{Binding}"
Margin="3" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
In diesem Beispiel erstellt die ViewCell für jeden Farbeintrag eine einfache BoxView:
Anmerkung
Verwenden Sie beim Definieren von Arrays allgemeiner Typen wie Zeichenfolgen oder Zahlen die in Übergeben von Argumentenaufgeführten XAML-Sprachgrundtypen.
x:Null-Markuperweiterung
Die x:Null
Markuperweiterung wird von der NullExtension Klasse unterstützt. Es hat keine Eigenschaften und ist einfach die XAML-Entsprechung des C#-schlüsselworts null
.
Das folgende XAML-Beispiel zeigt, wie die x:Null
-Markuperweiterung verwendet wird:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<Label Text="Text 1" />
<Label Text="Text 2" />
<Label Text="Text 3"
FontFamily="{x:Null}" />
<Label Text="Text 4" />
<Label Text="Text 5" />
</StackLayout>
</ContentPage>
In diesem Beispiel wird eine implizite Style für Label definiert, die eine Setter enthält, die die FontFamily
-Eigenschaft auf eine bestimmte Schriftart festlegt. Der dritte Label vermeidet jedoch die Verwendung der in der impliziten Formatvorlage definierten Schriftart, indem dessen FontFamily
auf x:Null
festgelegt wird.
DataTemplate-Markuperweiterung
Mit der DataTemplate Markuperweiterung können Sie einen Typ in eine DataTemplatekonvertieren. Es wird von der DataTemplateExtension-Klasse unterstützt, die eine TypeName
Eigenschaft vom Typ string
definiert, die auf den Namen des Typs festgelegt ist, der in eine DataTemplatekonvertiert werden soll. Die TypeName
-Eigenschaft ist die Inhaltseigenschaft von DataTemplateExtension. Daher können Sie bei XAML-Markupausdrücken, die mit geschweiften Klammern ausgedrückt werden, den Teil TypeName=
des Ausdrucks beseitigen.
Anmerkung
Mit dem XAML-Parser kann die DataTemplateExtension Klasse als DataTemplategekürzt werden.
Eine typische Verwendung dieser Markuperweiterung befindet sich in einer Shell-Anwendung, wie im folgenden Beispiel gezeigt:
<ShellContent Title="Monkeys"
Icon="monkey.png"
ContentTemplate="{DataTemplate views:MonkeysPage}" />
In diesem Beispiel wird MonkeysPage
von einer ContentPage in eine DataTemplatekonvertiert, die als Wert der ShellContent.ContentTemplate
-Eigenschaft festgelegt wird. Dadurch wird sichergestellt, dass MonkeysPage
nur erstellt wird, wenn die Navigation zur Seite stattfindet, anstatt beim Start der Anwendung.
Weitere Informationen zu Shell-Apps finden Sie unter Shell-.