Share via


Steuerelementvorlagen

Browse sample.Durchsuchen Sie den Beispielcode.

.NET Multiplatform App UI (.NET MAUI) Steuervorlagen ermöglichen es Ihnen, die visuelle Struktur von ContentView abgeleiteten benutzerdefinierten Steuerelementen und ContentPage abgeleiteten Seiten zu definieren. Steuerelementvorlagen trennen die Benutzeroberfläche (UI) für ein benutzerdefiniertes Steuerelement oder eine Seite von der Logik, die das Steuerelement oder die Seite implementiert. Zusätzliche Inhalte können auch an einer vordefinierten Stelle in benutzerdefinierten Steuerelementen mit Vorlagen oder Seiten mit Vorlagen eingefügt werden.

Beispielsweise können Sie eine Steuerelementvorlage erstellen, die die Benutzeroberfläche eines benutzerdefinierten Steuerelements neu definiert. Die Steuerelementvorlage kann anschließend von der erforderlichen Instanz des benutzerdefinierten Steuerelements genutzt werden. Alternativ kann auch eine Steuervorlage erstellt werden, die eine gemeinsame Benutzeroberfläche definiert, die von mehreren Seiten in einer App verwendet wird. Die Steuerelementvorlage kann anschließend von mehreren Seiten genutzt werden, wobei jede Seite ihren eindeutigen Inhalt anzeigt.

Erstellen einer ControlTemplate

Im folgenden Beispiel wird der Code für ein benutzerdefiniertes CardView-Steuerelement veranschaulicht:

public class CardView : ContentView
{
    public static readonly BindableProperty CardTitleProperty =
        BindableProperty.Create(nameof(CardTitle), typeof(string), typeof(CardView), string.Empty);
    public static readonly BindableProperty CardDescriptionProperty =
        BindableProperty.Create(nameof(CardDescription), typeof(string), typeof(CardView), string.Empty);

    public string CardTitle
    {
        get => (string)GetValue(CardTitleProperty);
        set => SetValue(CardTitleProperty, value);
    }

    public string CardDescription
    {
        get => (string)GetValue(CardDescriptionProperty);
        set => SetValue(CardDescriptionProperty, value);
    }
    ...
}

Die CardView-Klasse, die von der ContentView-Klasse abgeleitet wird, stellt ein benutzerdefiniertes Steuerelement dar, das Daten in einem Karten ähnlichen Layout anzeigt. Die Klasse enthält Eigenschaften, die von bindbaren Eigenschaften unterstützt werden, für die angezeigten Daten. Die CardView-Klasse definiert jedoch keine Benutzeroberfläche. Stattdessen wird die Benutzeroberfläche mithilfe einer Steuerelementvorlage definiert. Weitere Informationen zum Erstellen der von ContentView abgeleiteten benutzerdefinierten Steuerelemente finden Sie unter -ContentView.

Eine Steuerelementvorlage wird mit dem Typ ControlTemplate erstellt. Wenn Sie eine ControlTemplate-Klasse erstellen, kombinieren Sie View-Objekte, um die Benutzeroberfläche für ein benutzerdefiniertes Steuerelement oder eine Seite zu erstellen. Eine ControlTemplate-Klasse darf nur ein View als Stammelement aufweisen. In der Regel enthält das Stammelement jedoch andere View-Objekte. Die visuelle Struktur wird durch die Kombination dieser Objekte bestimmt.

Zwar kann eine ControlTemplate-Klasse inline definiert werden, jedoch besteht der übliche Ansatz zum Deklarieren einer ControlTemplate-Klasse darin, sie als Ressource in einem Ressourcenverzeichnis zu deklarieren. Da es sich bei Steuerelementvorlagen um Ressourcen handelt, unterliegen sie denselben Bereichsregeln, die für alle Ressourcen gelten. Wenn Sie beispielsweise eine Steuervorlage in Ihrem Ressourcenwörterbuch auf Appsebene deklarieren, kann die Vorlage überall in Ihrer App verwendet werden. Wenn Sie die Vorlage in einer Seite definieren, kann die Steuerelementvorlage nur auf dieser Seite verwendet werden. Für weitere Informationen über Ressourcen siehe Ressourcenwörterbücher.

Im folgenden XAML-Beispiel eine ControlTemplate-Klasse für CardView-Objekte veranschaulicht:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             ...>
    <ContentPage.Resources>
      <ControlTemplate x:Key="CardViewControlTemplate">
          <Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
                 BackgroundColor="{Binding CardColor}"
                 BorderColor="{Binding BorderColor}"
                 ...>
              <!-- UI objects that define the CardView visual structure -->
          </Frame>
      </ControlTemplate>
    </ContentPage.Resources>
    ...
</ContentPage>

Wenn eine ControlTemplate-Klasse als Ressource deklariert wird, muss sie einen mit dem x:Key-Attribut festgelegten Schlüssel enthalten, damit sie im Ressourcenverzeichnis identifiziert werden kann. In diesem Beispiel handelt es sich beim Stammelement von CardViewControlTemplate um ein Frame-Objekt. Das Frame-Objekt nutzt die Markuperweiterung RelativeSource, um BindingContext auf die Instanz des Laufzeitobjekts festzulegen, auf die die Vorlage angewendet wird. Diese wird auch als übergeordnetes Element mit Vorlagen bezeichnet. Das Frame Objekt verwendet eine Kombination von Steuerelementen, um die visuelle Struktur eines CardView Objekts zu definieren. Die Bindungsausdrücke dieser Objekte werden mit CardView-Eigenschaften aufgelöst, weil sie BindingContext vom Frame-Stammelement erben. Für weitere Informationen über die RelativeSource Markuperweiterung siehe Relative Bindungen.

Verwenden von ControlTemplate

Ein ControlTemplate-Objekt kann auf ein von ContentViewabgeleitetes benutzerdefiniertes Steuerelement angewendet werden, indem das Steuerelementvorlagenobjekt als ControlTemplate-Eigenschaft festgelegt wird. Entsprechend kann ein ControlTemplate-Objekt auf eine von ContentPage abgeleitete Seite angewendet werden, indem das Steuerelementvorlagenobjekt als ControlTemplate-Eigenschaft festgelegt wird. Wenn zur Laufzeit ein ControlTemplate-Objekt angewendet wird, werden alle in ControlTemplate definierten Steuerelemente zur visuellen Struktur des benutzerdefinierten Steuerelements mit Vorlagen oder der Seite mit Vorlagen hinzugefügt.

Das folgende Beispiel zeigt CardViewControlTemplate, das der ControlTemplate Eigenschaft von zwei CardView Objekten zugewiesen wird:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:ControlTemplateDemos.Controls"
             ...>
    <StackLayout Margin="30">
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="John Doe"
                           CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png"
                           ControlTemplate="{StaticResource CardViewControlTemplate}" />
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="Jane Doe"
                           CardDescription="Phasellus eu convallis mi. In tempus augue eu dignissim fermentum. Morbi ut lacus vitae eros lacinia."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png"
                           ControlTemplate="{StaticResource CardViewControlTemplate}" />
    </StackLayout>
</ContentPage>

In diesem Beispiel werden die Steuerelemente in CardViewControlTemplate Teil der visuellen Struktur aller CardView-Objekte. Da das Stammobjekt Frame für die Steuerelementvorlage das übergeordnete Element mit Vorlagen als BindingContext festlegt, werden die Bindungsausdrücke von Frame und dessen untergeordnete Elemente anhand der Eigenschaften der einzelnen CardView-Objekte aufgelöst.

Der folgende Screenshot zeigt die für CardViewControlTemplate angewendeten CardView Objekte:

Screenshot of two templated CardView objects.

Wichtig

Der Zeitpunkt, zu dem ein ControlTemplate auf eine Steuerelementinstanz angewendet wird, kann ermittelt werden, indem die OnApplyTemplate-Methode im benutzerdefinierten Steuerelement mit Vorlagen oder in der Seite mit Vorlagen überschrieben wird. Weitere Informationen finden Sie unter Abrufen eines benannten Elements aus einer Vorlage.

Übergeben von Parametern mit TemplateBinding

Die Markuperweiterung TemplateBinding bindet eine Eigenschaft eines in einem ControlTemplate-Objekt enthaltenen Elements an eine vom benutzerdefinierten Steuerelement mit Vorlagen oder der Seite mit Vorlagen definierte öffentliche Eigenschaft. Wenn Sie die Markuperweiterung TemplateBinding verwenden, können Eigenschaften des Steuerelements als Parameter der Vorlage fungieren. Wenn eine Eigenschaft für ein benutzerdefiniertes Steuerelement mit Vorlagen oder eine Seite mit Vorlagen festgelegt wird, wird daher dieser Wert an das Element übergeben, das TemplateBinding enthält.

Wichtig

Die Markuperweiterung TemplateBinding ermöglicht, dass die RelativeSource-Bindung aus der vorherigen Steuerungsvorlage entfernt werden kann, und ersetzt die Binding-Ausdrücke.

Die Markuperweiterung TemplateBinding definiert die folgenden Eigenschaften:

  • Die Eigenschaft Path vom Typ string, die den Pfad zur Eigenschaft definiert.
  • Die Eigenschaft Mode vom Typ BindingMode, die die Richtung für die Weitergabe von Änderungen zwischen der Quelle und dem Ziel definiert.
  • Die Eigenschaft Converter vom Typ IValueConverter, die den Bindungswertkonverter definiert.
  • Die Eigenschaft ConverterParameter vom Typ object, die den Parameter für den Bindungswertkonverter definiert.
  • Die Eigenschaft StringFormat vom Typ string, die das Zeichenfolgenformat für die Bindung definiert.

Die ContentProperty-Eigenschaft für die Markuperweiterung TemplateBinding ist Path. Daher kann der Abschnitt „Path=“ der Markuperweiterung ausgelassen werden, wenn der Pfad das erste Element im Ausdruck TemplateBinding ist. Weitere Informationen zur Verwendung dieser Eigenschaften in einem Bindungsausdruck finden Sie unter Datenbindung.

Warnung

Die Markuperweiterung TemplateBinding sollte nur in ControlTemplate verwendet werden. Wenn Sie jedoch versuchen, einen TemplateBinding-Ausdruck außerhalb von ControlTemplate zu verwenden, führt dies weder zu einem Buildfehler noch zu einer Ausnahme.

Im folgenden XAML-Beispiel wird ein ControlTemplate für CardView-Objekte veranschaulicht, das die Markuperweiterung TemplateBinding verwendet:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="CardViewControlTemplate">
            <Frame BackgroundColor="{TemplateBinding CardColor}"
                   BorderColor="{TemplateBinding BorderColor}"
                   ...>
                <!-- UI objects that define the CardView visual structure -->                   
            </Frame>
        </ControlTemplate>
    </ContentPage.Resources>
    ...
</ContentPage>

In diesem Beispiel löst die Markuperweiterung TemplateBinding Bindungsausdrücke für die Eigenschaften der CardView-Objekte auf. Die folgende Abbildung zeigt die App von CardViewControlTemplate auf die CardView-Objekte:

Screenshot of templated CardView objects.

Wichtig

Die Verwendung der Markuperweiterung TemplateBinding gleicht dem Festlegen des übergeordneten Elements mit Vorlagen für die BindingContext-Eigenschaft des Stammelements in der Vorlage mithilfe der Markuperweiterung RelativeSource und dem anschließenden Auflösen von Bindungen von untergeordneten Objekten mit der Markuperweiterung Binding. Durch die Markuperweiterung TemplateBinding wird ein Binding erstellt, dessen SourceRelativeBindingSource.TemplatedParent ist.

Anwenden von ControlTemplate mit einer Formatvorlage

Steuerelementvorlagen können auch mit Formatvorlagen angewendet werden. Hierzu wird eine implizite oder explizite Formatvorlage erstellt, die das ControlTemplate-Objekt verwendet.

Im folgenden XAML-Beispiel wird eine implizite Formatvorlage veranschaulicht, die CardViewControlTemplate verwendet:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:ControlTemplateDemos.Controls"
             ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="CardViewControlTemplate">
            ...
        </ControlTemplate>

        <Style TargetType="controls:CardView">
            <Setter Property="ControlTemplate"
                    Value="{StaticResource CardViewControlTemplate}" />
        </Style>
    </ContentPage.Resources>
    <StackLayout Margin="30">
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="John Doe"
                           CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png" />
        ...
    </StackLayout>
</ContentPage>

In diesem Beispiel wird implizitStyle automatisch auf jedes CardView-Objekt angewandt und setzt die ControlTemplate-Eigenschaft jedes CardView auf CardViewControlTemplate.

Weitere Informationen zu Formatvorlagen finden Sie unter -Formatvorlagen.

Neudefinieren der Benutzeroberfläche eines Steuerelements

Wenn ein ControlTemplate-Objekt instanziiert und der ControlTemplate-Eigenschaft eines von ContentView abgeleiteten benutzerdefinierten Steuerelements oder einer von ContentPage abgeleiteten Seite zugewiesen wird, wird die vom benutzerdefinierten Steuerelement oder der Seite definierte visuelle Struktur durch die in ControlTemplate definierte visuelle Struktur ersetzt.

Das benutzerdefinierte Steuerelement CardViewUI definiert die Benutzeroberfläche beispielsweise mithilfe des folgenden XAML-Codes:

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ControlTemplateDemos.Controls.CardViewUI"
             x:Name="this">
    <Frame BindingContext="{x:Reference this}"
           BackgroundColor="{Binding CardColor}"
           BorderColor="{Binding BorderColor}"
           ...>
        <!-- UI objects that define the CardView visual structure -->           
    </Frame>
</ContentView>

Die Steuerelemente, aus der sich diese Benutzeroberfläche zusammensetzt, können jedoch ersetzt werden, indem eine neue visuelle Struktur in einer ControlTemplate-Klasse definiert wird, die dann der ControlTemplate-Eigenschaft eines CardViewUI-Objekts zugewiesen wird:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="CardViewCompressed">
            <Grid RowDefinitions="100"
                  ColumnDefinitions="100, *">
                <Image Source="{TemplateBinding IconImageSource}"
                       BackgroundColor="{TemplateBinding IconBackgroundColor}"
                       ...>
                <!-- Other UI objects that define the CardView visual structure -->
            </Grid>
        </ControlTemplate>
    </ContentPage.Resources>
    <StackLayout Margin="30">
        <controls:CardViewUI BorderColor="DarkGray"
                             CardTitle="John Doe"
                             CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
                             IconBackgroundColor="SlateGray"
                             IconImageSource="user.png"
                             ControlTemplate="{StaticResource CardViewCompressed}" />
        ...
    </StackLayout>
</ContentPage>

In diesem Beispiel wird die visuelle Struktur des CardViewUI-Objekts in einer ControlTemplate-Klasse neu definiert, die eine kompaktere visuelle Struktur bereitstellt, die sich für eine komprimierte Liste eignet:

Screenshot of templated CardViewUI objects.

Ersetzen von Inhalten in ContentPresenter

Eine ContentPresenter-Klasse kann in einer Steuerelementvorlage platziert werden, um zu markieren, wo Inhalt vom benutzerdefinierten Steuerelement mit Vorlagen oder der Seite mit Vorlagen angezeigt werden soll. Das benutzerdefinierte Steuerelement oder die Seite, die die Steuerelementvorlage nutzen, definieren dann den Inhalt, der von ContentPresenter angezeigt werden soll. Das folgende Diagramm veranschaulicht eine ControlTemplate-Klasse für eine Seite mit einer Reihe von Steuerelementen. Zusätzlich abgebildet ist eine ContentPresenter-Klasse, hier dargestellt durch ein blaues Rechteck:

Control template for a ContentPage.

Im folgenden XAML-Code wird eine Steuerelementvorlage namens TealTemplate veranschaulicht, die eine ContentPresenter-Klasse in der visuellen Struktur enthält:

<ControlTemplate x:Key="TealTemplate">
    <Grid RowDefinitions="0.1*, 0.8*, 0.1*">
        <BoxView Color="Teal" />
        <Label Margin="20,0,0,0"
               Text="{TemplateBinding HeaderText}"
               ... />
        <ContentPresenter Grid.Row="1" />
        <BoxView Grid.Row="2"
                 Color="Teal" />
        <Label x:Name="changeThemeLabel"
               Grid.Row="2"
               Margin="20,0,0,0"
               Text="Change Theme"
               ...>
            <Label.GestureRecognizers>
                <TapGestureRecognizer Tapped="OnChangeThemeLabelTapped" />
            </Label.GestureRecognizers>
        </Label>
        <controls:HyperlinkLabel Grid.Row="2"
                                 Margin="0,0,20,0"
                                 Text="Help"
                                 Url="https://learn.microsoft.com/dotnet/maui/"
                                 ... />
    </Grid>
</ControlTemplate>

Im folgenden Beispiel wird veranschaulicht, wie TealTemplate zur ControlTemplate-Eigenschaft einer von ContentPage abgeleiteten Seite zugewiesen wird:

<controls:HeaderFooterPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                           xmlns:controls="clr-namespace:ControlTemplateDemos.Controls"                           
                           ControlTemplate="{StaticResource TealTemplate}"
                           HeaderText="MyApp"
                           ...>
    <StackLayout Margin="10">
        <Entry Placeholder="Enter username" />
        <Entry Placeholder="Enter password"
               IsPassword="True" />
        <Button Text="Login" />
    </StackLayout>
</controls:HeaderFooterPage>

Wenn TealTemplate zur Laufzeit auf die Seite angewendet wird, wird der Seiteninhalt in das ContentPresenter-Element eingefügt, das in der Steuerelementvorlage definiert wird:

Screenshot of templated page object.

Abrufen eines benannten Elements aus einer Vorlage

Benannte Elemente innerhalb einer Steuerelementvorlage können aus dem benutzerdefinierten Steuerelement mit Vorlagen oder der Seite mit Vorlagen abgerufen werden. Hierzu dient die GetTemplateChild-Methode, die das benannte Element in der instanziierten visuellen ControlTemplate-Struktur zurückgibt, wenn es gefunden wird. Andernfalls wird nullzurückgegeben.

Nachdem eine Steuerelementvorlage instanziiert wurde, wird die OnApplyTemplate-Methode der Vorlage aufgerufen. Die GetTemplateChild-Methode sollte daher über eine OnApplyTemplate-Außerkraftsetzung im Steuerelement mit Vorlagen oder der Seite mit Vorlagen aufgerufen werden.

Wichtig

Die GetTemplateChild-Methode sollte nur nach dem Aufruf der OnApplyTemplate-Methode aufgerufen werden.

Im folgenden XAML-Code wird eine Steuerelementvorlage namens TealTemplate veranschaulicht, die auf von ContentPage abgeleitete Seiten angewendet werden kann:

<ControlTemplate x:Key="TealTemplate">
    <Grid>
        ...
        <Label x:Name="changeThemeLabel"
               Text="Change Theme"
               ...>
            <Label.GestureRecognizers>
                <TapGestureRecognizer Tapped="OnChangeThemeLabelTapped" />
            </Label.GestureRecognizers>
        </Label>
        ...
    </Grid>
</ControlTemplate>

Im folgenden Beispiel wird das Label-Element benannt, das im Code für die Seite mit Vorlagen abgerufen werden kann. Hierzu wird die GetTemplateChild-Methode der OnApplyTemplate-Außerkraftsetzung für die Seite mit Vorlagen aufgerufen:

public partial class AccessTemplateElementPage : HeaderFooterPage
{
    Label themeLabel;

    public AccessTemplateElementPage()
    {
        InitializeComponent();
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        themeLabel = (Label)GetTemplateChild("changeThemeLabel");
        themeLabel.Text = OriginalTemplate ? "Aqua Theme" : "Teal Theme";
    }
}

In diesem Beispiel wurde das Label-Objekt namens changeThemeLabel abgerufen, sobald ControlTemplate instanziiert wurde. changeThemeLabel kann anschließend von der AccessTemplateElementPage-Klasse aufgerufen und bearbeitet werden. Der folgende Screenshot zeigt, dass der durch Label angezeigte Text geändert wurde:

Screenshot of templated page object that's changed.

Einbindung in ViewModel

Eine ControlTemplate-Klasse kann eine Datenbindung mit einem ViewModel-Element auch dann herstellen, wenn die ControlTemplate-Klasse in das übergeordnete Element mit Vorlagen eingebunden ist (die Laufzeitobjektinstanz, auf die die Vorlage angewendet wird).

Im folgenden XAML-Beispiel wird eine Seite veranschaulicht, die ein ViewModel-Element namens PeopleViewModel verwendet:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ControlTemplateDemos"
             xmlns:controls="clr-namespace:ControlTemplateDemos.Controls"
             ...>
    <ContentPage.BindingContext>
        <local:PeopleViewModel />
    </ContentPage.BindingContext>

    <ContentPage.Resources>
        <DataTemplate x:Key="PersonTemplate">
            <controls:CardView BorderColor="DarkGray"
                               CardTitle="{Binding Name}"
                               CardDescription="{Binding Description}"
                               ControlTemplate="{StaticResource CardViewControlTemplate}" />
        </DataTemplate>
    </ContentPage.Resources>

    <StackLayout Margin="10"
                 BindableLayout.ItemsSource="{Binding People}"
                 BindableLayout.ItemTemplate="{StaticResource PersonTemplate}" />
</ContentPage>

In diesem Beispiel wird eine PeopleViewModel-Instanz für die BindingContext-Eigenschaft der Seite festgelegt. Dieses ViewModel-Element stellt eine People-Sammlung und eine ICommand-Schnittstelle namens DeletePersonCommand zur Verfügung. Die StackLayout-Klasse der Seite verwendet ein bindbares Layouts, um eine Datenbindung mit der People-Sammlung herzustellen. Die ItemTemplate-Eigenschaft des bindbaren Layouts wird auf die Ressource PersonTemplate festgelegt. Diese DataTemplate-Klasse legt fest, dass alle Elemente in der People-Sammlung mithilfe eines CardView-Objekts angezeigt werden. Die visuelle Struktur des CardView-Objekts wird mithilfe einer ControlTemplate-Klasse namens CardViewControlTemplate definiert:

<ControlTemplate x:Key="CardViewControlTemplate">
    <Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
           BackgroundColor="{Binding CardColor}"
           BorderColor="{Binding BorderColor}"
           ...>
        <!-- UI objects that define the CardView visual structure -->           
    </Frame>
</ControlTemplate>

In diesem Beispiel handelt es sich beim Stammelement von ControlTemplate um ein Frame-Objekt. Das Objekt Frame verwendet die Markuperweiterung RelativeSource, um das übergeordnete Element mit Vorlagen für BindingContext festzulegen. Die Bindungsausdrücke des Frame-Objekts und dessen untergeordneten Elemente werden mit CardView-Eigenschaften aufgelöst, weil sie BindingContext vom Frame-Stammelement erben. Die folgende Abbildung zeigt die Seite, auf der die Sammlung People angezeigt wird:

Screenshot of three templated CardView objects that bind to a viewmodel.

Während die Objekte in ControlTemplate Eigenschaften nur an das übergeordnete Element mit Vorlagen binden, wird die Button-Klasse in der Steuerelementvorlage sowohl an das übergeordnete Element mit Vorlagen als auch an die DeletePersonCommand-Eigenschaft im ViewModel-Element gebunden. Dies liegt daran, dass Eigenschaft Button.Command ihre Bindungsquelle als Bindungskontext des Vorgängers neu definiert, dessen Bindungskontexttyp PeopleViewModel ist. Dabei handelt es sich um die StackLayout-Klasse. Der Abschnitt Path der Bindungsausdrücke kann dann die DeletePersonCommand-Eigenschaft auflösen. Die Button.CommandParameter-Eigenschaft ändert jedoch nicht ihre Bindungsquelle, stattdessen erbt sie sie vom übergeordneten Element in der ControlTemplate-Klasse. Daher wird die CommandParameter-Eigenschaft an die CardTitle-Eigenschaft von CardView gebunden.

Der Gesamteffekt der Button-Bindungen besteht darin, dass DeletePersonCommand in der PeopleViewModel-Klasse ausgeführt wird, wenn auf das Button-Element getippt wird, wodurch der Wert der CardName-Eigenschaft an DeletePersonCommand übergeben wird. Dies führt dazu, dass der angegebene CardView aus dem bindbaren Layout entfernt wird.

Für weitere Informationen über relative Bindungen, siehe Relative Bindungen.