Freigeben über


Verwenden von XAML-Markuperweiterungen

Beispiel durchsuchen. Beispiel durchsuchen

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:

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:Staticabgekü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 Memberverweist, 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.PIfestgelegt werden. Dies führt zu eher kleinem Text, sodass die eigenschaft Scale auf Math.Efestgelegt ist:

<Label Text="&#x03C0; &#x00D7; 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:Static demo.

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:Nameeinen 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}&#x00B0; 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:Reference Demo.

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:

x:Type demo.

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 Typ Type, der den Typ der Elemente im Array angibt. Diese Eigenschaft sollte auf eine x:Type-Markup-Erweiterung festgelegt werden.
  • Items vom Typ IList, 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:

x:Array demo.

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:Nullfestgelegt wird.

x:Null-Demo.

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 stringdefiniert, 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-.