Freigeben über


Teil 3. XAML-Markuperweiterungen

XAML-Markuperweiterungen stellen ein wichtiges Feature in XAML dar, mit dem Eigenschaften auf Objekte oder Werte festgelegt werden können, auf die indirekt aus anderen Quellen verwiesen wird. XAML-Markuperweiterungen sind besonders wichtig für das Freigeben von Objekten und verweisen auf Konstanten, die in einer Anwendung verwendet werden, aber sie finden ihr größtes Dienstprogramm in Datenbindungen.

XAML-Markuperweiterungen

Im Allgemeinen verwenden Sie XAML, um Eigenschaften eines Objekts auf explizite Werte festzulegen, z. B. eine Zeichenfolge, eine Zahl, ein Enumerationselement oder eine Zeichenfolge, die hinter den Kulissen in einen Wert konvertiert wird.

Manchmal müssen Eigenschaften jedoch stattdessen auf Werte verweisen, die an anderer Stelle definiert sind, oder die zur Laufzeit eine kleine Bearbeitung durch den Code erfordern. Für diese Zwecke sind XAML-Markup-Erweiterungen verfügbar.

Diese XAML-Markuperweiterungen sind keine Xml-Erweiterungen. XAML ist völlig legales XML. Sie werden als "Erweiterungen" bezeichnet, da sie von Code in Klassen unterstützt werden, die implementiert IMarkupExtensionwerden. Sie können eigene benutzerdefinierte Markuperweiterungen schreiben.

In vielen Fällen sind XAML-Markuperweiterungen in XAML-Dateien sofort erkennbar, da sie als Attributeinstellungen angezeigt werden, die durch geschweifte Klammern getrennt sind: { und }, aber manchmal werden Markuperweiterungen in Markup als herkömmliche Elemente angezeigt.

Gemeinsam genutzte Ressourcen

Einige XAML-Seiten enthalten mehrere Ansichten, deren Eigenschaften auf dieselben Werte festgelegt sind. Zum Beispiel sind viele der Eigenschaftseinstellungen für diese Button-Objekte gleich:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">

    <StackLayout>
        <Button Text="Do this!"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />

        <Button Text="Do that!"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />

        <Button Text="Do the other thing!"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />

    </StackLayout>
</ContentPage>

Wenn eine dieser Eigenschaften geändert werden muss, ist es besser, die Änderung nur einmal und nicht dreimal vornehmen zu müssen. Wäre es Code, würden Sie wahrscheinlich Konstanten und statische schreibgeschützte Objekte verwenden, um diese Werte konsistent und einfach änderbar zu halten.

In XAML besteht eine beliebte Lösung darin, solche Werte oder Objekte in einem Ressourcenwörterbuch zu speichern. Die Klasse VisualElement definiert eine Eigenschaft namens Resources vom Typ ResourceDictionary, die ein Wörterbuch mit Schlüsseln vom Typ string und Werten vom Typ object ist. Sie können Objekte in diesem Wörterbuch ablegen und sie dann in XAML aus dem Markup referenzieren.

Um ein Ressourcenwörterbuch auf einer Seite zu verwenden, schließen Sie ein Paar von Resources Eigenschaftselementtags ein. Es ist am bequemsten, diese am oberen Rand der Seite zu platzieren:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">

    <ContentPage.Resources>

    </ContentPage.Resources>
    ...
</ContentPage>

Es ist auch erforderlich, Tags explizit einzuschließen ResourceDictionary :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">

    <ContentPage.Resources>
        <ResourceDictionary>

        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

Objekte und Werte verschiedener Typen können nun dem Ressourcenwörterbuch hinzugefügt werden. Diese Typen müssen instanziierbar sein. Sie dürfen z. B. keine abstrakten Klassen sein. Diese Typen müssen außerdem einen öffentlichen Konstruktor ohne Parameter haben. Für jedes Element ist ein Wörterbuchschlüssel erforderlich, der mit dem x:Key Attribut angegeben ist. Zum Beispiel:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">

    <ContentPage.Resources>
        <ResourceDictionary>
            <LayoutOptions x:Key="horzOptions"
                           Alignment="Center" />

            <LayoutOptions x:Key="vertOptions"
                           Alignment="Center"
                           Expands="True" />
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

Diese beiden Elemente sind Werte des Strukturtyps LayoutOptions, und jede hat einen eindeutigen Schlüssel und eine oder zwei Eigenschaften festgelegt. In Code und Markup ist es weitaus gebräuchlicher, die statischen Felder von LayoutOptions zu verwenden, aber hier ist es bequemer, die Eigenschaften festzulegen.

Jetzt ist es erforderlich, die HorizontalOptions Eigenschaften VerticalOptions und Eigenschaften dieser Schaltflächen auf diese Ressourcen festzulegen, und das geschieht mit der StaticResource XAML-Markuperweiterung:

<Button Text="Do this!"
        HorizontalOptions="{StaticResource horzOptions}"
        VerticalOptions="{StaticResource vertOptions}"
        BorderWidth="3"
        Rotation="-15"
        TextColor="Red"
        FontSize="24" />

Die Markup-Erweiterung StaticResource wird immer mit geschweiften Klammern abgegrenzt und enthält den Wörterbuchschlüssel.

Der Name StaticResource unterscheidet ihn von DynamicResourcedem, von dem Xamarin.Forms auch unterstützt wird. DynamicResource ist für Wörterbuchschlüssel vorgesehen, die sich während der Laufzeit ändern können, während StaticResource nur einmal auf Elemente aus dem Wörterbuch zugegriffen wird, wenn die Elemente auf der Seite erstellt werden.

Für die BorderWidth Eigenschaft ist es erforderlich, ein Double im Wörterbuch zu speichern. XAML definiert praktischerweise Tags für gängige Datentypen wie x:Double und x:Int32:

<ContentPage.Resources>
    <ResourceDictionary>
        <LayoutOptions x:Key="horzOptions"
                       Alignment="Center" />

        <LayoutOptions x:Key="vertOptions"
                       Alignment="Center"
                       Expands="True" />

        <x:Double x:Key="borderWidth">
            3
        </x:Double>
    </ResourceDictionary>
</ContentPage.Resources>

Sie müssen sie nicht in drei Zeilen setzen. Dieser Wörterbucheintrag für diesen Drehwinkel benötigt nur eine Zeile:

<ContentPage.Resources>
    <ResourceDictionary>
        <LayoutOptions x:Key="horzOptions"
                       Alignment="Center" />

        <LayoutOptions x:Key="vertOptions"
                       Alignment="Center"
                       Expands="True" />

         <x:Double x:Key="borderWidth">
            3
         </x:Double>

        <x:Double x:Key="rotationAngle">-15</x:Double>
    </ResourceDictionary>
</ContentPage.Resources>

Auf diese beiden Ressourcen kann auf die gleiche Weise wie auf die LayoutOptions Werte verwiesen werden:

<Button Text="Do this!"
        HorizontalOptions="{StaticResource horzOptions}"
        VerticalOptions="{StaticResource vertOptions}"
        BorderWidth="{StaticResource borderWidth}"
        Rotation="{StaticResource rotationAngle}"
        TextColor="Red"
        FontSize="24" />

Für Ressourcen vom Typ Color können Sie dieselben Zeichenkettendarstellungen verwenden, die Sie auch bei der direkten Zuweisung von Attributen dieses Typs verwenden. Die Typkonverter werden aufgerufen, wenn die Ressource erstellt wird. Dies ist eine Ressource vom Typ Color:

<Color x:Key="textColor">Red</Color>

Häufig legen Programme eine FontSize Eigenschaft auf ein Element der NamedSize Enumeration fest, z Large. B. . Die FontSizeConverter Klasse arbeitet hinter den Kulissen, um sie mithilfe der Device.GetNamedSized Methode in einen plattformabhängigen Wert umzuwandeln. Beim Definieren einer Schriftgradressource ist es jedoch sinnvoller, einen numerischen Wert zu verwenden, der hier als x:Double Typ dargestellt wird:

<x:Double x:Key="fontSize">24</x:Double>

Jetzt werden alle Eigenschaften außer Text durch Ressourceneinstellungen definiert:

<Button Text="Do this!"
        HorizontalOptions="{StaticResource horzOptions}"
        VerticalOptions="{StaticResource vertOptions}"
        BorderWidth="{StaticResource borderWidth}"
        Rotation="{StaticResource rotationAngle}"
        TextColor="{StaticResource textColor}"
        FontSize="{StaticResource fontSize}" />

Es ist auch möglich, OnPlatform innerhalb des Ressourcenwörterbuchs unterschiedliche Werte für die Plattformen zu definieren. Hier erfahren Sie, wie ein OnPlatform Objekt Teil des Ressourcenwörterbuchs für verschiedene Textfarben sein kann:

<OnPlatform x:Key="textColor"
            x:TypeArguments="Color">
    <On Platform="iOS" Value="Red" />
    <On Platform="Android" Value="Aqua" />
    <On Platform="UWP" Value="#80FF80" />
</OnPlatform>

Beachten Sie, dass OnPlatform sowohl ein x:Key Attribut als auch ein Objekt im Wörterbuch und ein x:TypeArguments Attribut abruft, da es sich um eine generische Klasse handelt. Die iOSAttribute Androidund UWP Attribute werden beim Initialisieren des Objekts in Color Werte konvertiert.

Hier ist die endgültige vollständige XAML-Datei mit drei Schaltflächen, die auf sechs freigegebene Werte zugreifen:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">

    <ContentPage.Resources>
        <ResourceDictionary>
            <LayoutOptions x:Key="horzOptions"
                           Alignment="Center" />

            <LayoutOptions x:Key="vertOptions"
                           Alignment="Center"
                           Expands="True" />

            <x:Double x:Key="borderWidth">3</x:Double>

            <x:Double x:Key="rotationAngle">-15</x:Double>

            <OnPlatform x:Key="textColor"
                        x:TypeArguments="Color">
                <On Platform="iOS" Value="Red" />
                <On Platform="Android" Value="Aqua" />
                <On Platform="UWP" Value="#80FF80" />
            </OnPlatform>

            <x:Double x:Key="fontSize">24</x:Double>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <Button Text="Do this!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />

        <Button Text="Do that!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />

        <Button Text="Do the other thing!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />

    </StackLayout>
</ContentPage>

Die Screenshots überprüfen die konsistente Formatierung und die plattformabhängige Formatierung:

Formatierte Steuerelemente

Obwohl es am häufigsten ist, die Resources Auflistung am oberen Rand der Seite zu definieren, denken Sie daran, dass die Resources Eigenschaft durch VisualElementdefiniert wird, und Sie können Sammlungen auf anderen Elementen auf der Seite haben Resources . Versuchen Sie beispielsweise, eins StackLayout zum folgenden Beispiel hinzuzufügen:

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <Color x:Key="textColor">Blue</Color>
        </ResourceDictionary>
    </StackLayout.Resources>
    ...
</StackLayout>

Sie werden feststellen, dass die Textfarbe der Schaltflächen jetzt blau ist. Grundsätzlich sucht der XAML-Parser, wenn der XAML-Parser auf eine StaticResource Markuperweiterung trifft, die visuelle Struktur und verwendet die erste ResourceDictionary Gefundene, die diesen Schlüssel enthält.

Einer der am häufigsten in Ressourcenwörterbüchern gespeicherten Objekttypen ist der Xamarin.FormsStyle, der eine Auflistung von Eigenschafteneinstellungen definiert. Formatvorlagen werden im Artikel "Formatvorlagen" erläutert.

Manchmal fragen sich Entwickler mit XAML, ob sie ein visuelles Element wie Label oder Button in einem ResourceDictionary. Obwohl es sicher möglich ist, macht es nicht viel Sinn. Der Zweck besteht ResourceDictionary darin, Objekte gemeinsam zu nutzen. Ein visuelles Element kann nicht freigegeben werden. Dieselbe Instanz kann nicht zweimal auf einer einzelnen Seite angezeigt werden.

Die x:Static-Markuperweiterung

Trotz der Ähnlichkeiten ihrer Namen x:Static und StaticResource sehr unterschiedlich. StaticResource gibt ein Objekt aus einem Ressourcenverzeichnis zurück, während x:Static auf eines der folgenden Elemente zugegriffen wird:

  • ein öffentliches statisches Feld
  • eine öffentliche statische Eigenschaft
  • ein öffentliches Konstantenfeld
  • ein Enumerationselement.

Die Markup-Erweiterung StaticResource wird von XAML-Implementierungen unterstützt, die ein Ressourcen-Wörterbuch definieren, während x:Static ein fester Bestandteil von XAML ist, wie das Präfix x zeigt.

Im Folgenden finden Sie einige Beispiele, die veranschaulichen, wie x:Static explizit auf statische Felder und Enumerationsmember verwiesen werden kann:

<Label Text="Hello, XAML!"
       VerticalOptions="{x:Static LayoutOptions.Start}"
       HorizontalTextAlignment="{x:Static TextAlignment.Center}"
       TextColor="{x:Static Color.Aqua}" />

Bisher ist dies nicht sehr beeindruckend. x:Static Die Markuperweiterung kann jedoch auch auf statische Felder oder Eigenschaften aus Ihrem eigenen Code verweisen. Hier ist beispielsweise eine AppConstants Klasse, die einige statische Felder enthält, die Sie möglicherweise auf mehreren Seiten in einer Anwendung verwenden möchten:

using System;
using Xamarin.Forms;

namespace XamlSamples
{
    static class AppConstants
    {
        public static readonly Thickness PagePadding;

        public static readonly Font TitleFont;

        public static readonly Color BackgroundColor = Color.Aqua;

        public static readonly Color ForegroundColor = Color.Brown;

        static AppConstants()
        {
            switch (Device.RuntimePlatform)
            {
                case Device.iOS:
                    PagePadding = new Thickness(5, 20, 5, 0);
                    TitleFont = Font.SystemFontOfSize(35, FontAttributes.Bold);
                    break;

                case Device.Android:
                    PagePadding = new Thickness(5, 0, 5, 0);
                    TitleFont = Font.SystemFontOfSize(40, FontAttributes.Bold);
                    break;

                case Device.UWP:
                    PagePadding = new Thickness(5, 0, 5, 0);
                    TitleFont = Font.SystemFontOfSize(50, FontAttributes.Bold);
                    break;
            }
        }
    }
}

Um auf die statischen Felder dieser Klasse in der XAML-Datei zu verweisen, müssen Sie in der XAML-Datei angeben, wo sich diese Datei befindet. Dazu verwenden Sie eine XML-Namespacedeklaration.

Denken Sie daran, dass die XAML-Dateien, die als Teil der Standard-XAML-Vorlage Xamarin.Forms erstellt wurden, zwei XML-Namespacedeklarationen enthalten: eine für den Zugriff auf Klassen und eine andere für das Verweisen auf Xamarin.Forms Tags und Attribute, die in XAML systemintern sind:

xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

Sie benötigen zusätzliche XML-Namespacedeklarationen, um auf andere Klassen zuzugreifen. Jede weitere XML-Namespace-Deklaration definiert ein neues Präfix. Für den Zugriff auf Klassen lokal auf die freigegebene .NET Standard-Bibliothek, z AppConstants. B. xaml-Programmierer, verwenden häufig das Präfix local. Die Namespace-Deklaration muss den CLR-Namespace-Namen (Common Language Runtime) angeben, der auch als .NET-Namespace-Name bekannt ist. Dies ist der Name, der in einer C# namespace-Definition oder in einer using-Direktive erscheint:

xmlns:local="clr-namespace:XamlSamples"

Sie können auch XML-Namespacedeklarationen für .NET-Namespaces in jeder Assembly definieren, auf die die .NET Standard-Bibliothek verweist. Hier sehen Sie beispielsweise ein sys Präfix für den standardmäßigen .NET-Namespace System , der sich in der netstandard-Assembly befindet. Da es sich um eine andere Assembly handelt, müssen Sie auch den Assemblynamen angeben, in diesem Fall netstandard:

xmlns:sys="clr-namespace:System;assembly=netstandard"

Beachten Sie, dass auf den Schlüsselwort (keyword) clr-namespace ein Doppelpunkt und dann der .NET-Namespacename gefolgt von einem Semikolon, dem Schlüsselwort (keyword)assembly, einem Gleichheitszeichen und dem Assemblynamen folgt.

Ja, ein Doppelpunkt folgt clr-namespace , aber gleichheitszeichen folgt assembly. Die Syntax wurde auf diese Weise bewusst definiert: Die meisten XML-Namespacedeklarationen verweisen auf einen URI, der einen URI-Schemanamen beginnt, z http. B. , auf den immer ein Doppelpunkt folgt. Der clr-namespace Teil dieser Zeichenfolge soll diese Konvention nachahmen.

Beide Namespacedeklarationen sind im StaticConstantsPage-Beispiel enthalten. Beachten Sie, dass die BoxView Dimensionen auf Math.PI und Math.E, jedoch um einen Faktor von 100 skaliert werden:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="XamlSamples.StaticConstantsPage"
             Title="Static Constants Page"
             Padding="{x:Static local:AppConstants.PagePadding}">

    <StackLayout>
       <Label Text="Hello, XAML!"
              TextColor="{x:Static local:AppConstants.BackgroundColor}"
              BackgroundColor="{x:Static local:AppConstants.ForegroundColor}"
              Font="{x:Static local:AppConstants.TitleFont}"
              HorizontalOptions="Center" />

      <BoxView WidthRequest="{x:Static sys:Math.PI}"
               HeightRequest="{x:Static sys:Math.E}"
               Color="{x:Static local:AppConstants.ForegroundColor}"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               Scale="100" />
    </StackLayout>
</ContentPage>

Die Größe der resultierenden BoxView relativ zum Bildschirm ist plattformabhängig:

Steuerelemente mit x:Static Markup Extension

Andere Standardmarkuperweiterungen

Mehrere Markuperweiterungen sind in XAML systemintern und werden in Xamarin.Forms XAML-Dateien unterstützt. Einige davon werden nicht sehr häufig verwendet, sind aber für die folgenden Fälle unerlässlich:

  • Wenn eine Eigenschaft standardmäßig einen Nicht-null-Wert hat, Sie sie aber auf null festlegen möchten, setzen Sie sie auf die Markup-Erweiterung {x:Null}.
  • Wenn eine Eigenschaft den Typ Type hat, können Sie sie mit der Markup-Erweiterung {x:Type someClass} einem Type-Objekt zuweisen.
  • Sie können Arrays in XAML mit der Markup-Erweiterung x:Array definieren. Diese Markup-Erweiterung hat ein erforderliches Attribut namens Type, das den Typ der Elemente im Array angibt.
  • Die Binding Markuperweiterung wird in Teil 4 erläutert. Grundlagen der Datenbindung.
  • Die RelativeSource Markuperweiterung wird in relativen Bindungen erläutert.

Die ConstraintExpression-Markuperweiterung

Markup-Erweiterungen können Eigenschaften haben, aber sie werden nicht wie XML-Attribute festgelegt. In einer Markup-Erweiterung werden die Eigenschaftseinstellungen durch Kommas getrennt, und innerhalb der geschweiften Klammern erscheinen keine Anführungszeichen.

Dies kann mit der Xamarin.Forms Markuperweiterung namens ConstraintExpressiondargestellt werden, die mit der RelativeLayout Klasse verwendet wird. Sie können die Position oder Größe einer untergeordneten Ansicht als Konstante oder relativ zu einer übergeordneten oder anderen benannten Ansicht angeben. Mit der Syntax der ConstraintExpression Ansicht können Sie die Position oder Größe einer Ansicht mithilfe einer Factor Uhrzeit einer Eigenschaft einer anderen Ansicht sowie einer .Constant Etwas komplexer als das erfordert Code.

Hier ist ein Beispiel angegeben:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.RelativeLayoutPage"
             Title="RelativeLayout Page">

    <RelativeLayout>

        <!-- Upper left -->
        <BoxView Color="Red"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=Constant,
                                            Constant=0}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=Constant,
                                            Constant=0}" />
        <!-- Upper right -->
        <BoxView Color="Green"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Width,
                                            Factor=1,
                                            Constant=-40}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=Constant,
                                            Constant=0}" />
        <!-- Lower left -->
        <BoxView Color="Blue"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=Constant,
                                            Constant=0}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Height,
                                            Factor=1,
                                            Constant=-40}" />
        <!-- Lower right -->
        <BoxView Color="Yellow"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Width,
                                            Factor=1,
                                            Constant=-40}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Height,
                                            Factor=1,
                                            Constant=-40}" />

        <!-- Centered and 1/3 width and height of parent -->
        <BoxView x:Name="oneThird"
                 Color="Red"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Width,
                                            Factor=0.33}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Height,
                                            Factor=0.33}"
                 RelativeLayout.WidthConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Width,
                                            Factor=0.33}"
                 RelativeLayout.HeightConstraint=
                     "{ConstraintExpression Type=RelativeToParent,
                                            Property=Height,
                                            Factor=0.33}"  />

        <!-- 1/3 width and height of previous -->
        <BoxView Color="Blue"
                 RelativeLayout.XConstraint=
                     "{ConstraintExpression Type=RelativeToView,
                                            ElementName=oneThird,
                                            Property=X}"
                 RelativeLayout.YConstraint=
                     "{ConstraintExpression Type=RelativeToView,
                                            ElementName=oneThird,
                                            Property=Y}"
                 RelativeLayout.WidthConstraint=
                     "{ConstraintExpression Type=RelativeToView,
                                            ElementName=oneThird,
                                            Property=Width,
                                            Factor=0.33}"
                 RelativeLayout.HeightConstraint=
                     "{ConstraintExpression Type=RelativeToView,
                                            ElementName=oneThird,
                                            Property=Height,
                                            Factor=0.33}"  />
    </RelativeLayout>
</ContentPage>

Vielleicht die wichtigste Lektion, die Sie aus diesem Beispiel ziehen sollten, ist die Syntax der Markuperweiterung: Es müssen keine Anführungszeichen in den geschweiften Klammern einer Markuperweiterung angezeigt werden. Beim Eingeben der Markuperweiterung in einer XAML-Datei ist es natürlich, die Werte der Eigenschaften in Anführungszeichen einzuschließen. Widerstehen Sie der Versuchung!

Dies ist das Programm, das ausgeführt wird:

Relatives Layout mit Einschränkungen

Zusammenfassung

Die hier gezeigten XAML-Markuperweiterungen bieten wichtige Unterstützung für XAML-Dateien. Aber vielleicht ist die wertvollste XAML-Markuperweiterung Binding, die im nächsten Teil dieser Reihe, Teil 4, behandelt wird. Grundlagen der Datenbindung.