Udostępnij za pośrednictwem


Powiązania podstawowe

Browse sample. Przeglądanie przykładu

Powiązanie danych interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI) łączy parę właściwości między dwoma obiektami, z których co najmniej jeden jest zwykle obiektem interfejsu użytkownika. Te dwa obiekty noszą nazwę obiektu docelowego i obiektu źródłowego:

  • Obiekt docelowy to obiekt (i właściwość), na którym jest ustawione powiązanie danych.
  • Obiekt źródłowy to obiekt (i właściwość), do którego odwołuje się powiązanie danych.

W najprostszym przypadku dane przepływają od obiektu źródłowego do obiektu docelowego, co oznacza, że wartość właściwości docelowej jest ustawiana na podstawie wartości właściwości źródłowej. Jednak w niektórych przypadkach dane mogą przepływać od obiektu docelowego do obiektu źródłowego lub w obu kierunkach.

Ważne

Obiekt docelowy jest zawsze obiektem, na którym jest ustawiane powiązanie danych, nawet jeśli dostarcza dane, a nie odbiera dane.

Powiązania z kontekstem powiązania

Rozważmy następujący przykład XAML, którego celem jest rotacja elementu Label przez manipulowanie elementem Slider:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Bez powiązań danych należałoby ustawić zdarzenie ValueChanged obiektu Slider na program obsługi zdarzeń, który uzyskuje dostęp do właściwości Value obiektu Slider i ustawia dla niej wartość właściwości Rotation obiektu Label. Powiązanie danych automatyzuje to zadanie, a więc program obsługi zdarzeń i kod w nim nie są już niezbędne.

Powiązanie można ustawić na wystąpieniu dowolnej klasy, która pochodzi od klasy BindableObject obejmującej pochodne Element, VisualElement, View i View. Powiązanie jest zawsze ustawiane na obiekcie docelowym. Powiązanie odwołuje się do obiektu źródłowego. Aby ustawić powiązanie danych, użyj następujących dwóch elementów członkowskich klasy docelowej:

  • Właściwość BindingContext określa obiekt źródłowy.
  • Metoda SetBinding określa właściwość docelową i właściwość źródłową.

W tym przykładzie Label jest obiektem docelowym powiązania, a Slider — obiektem źródłowym powiązania. Zmiany w obiekcie źródłowym Slider wpływają na obrót obiektu docelowego Label. Dane przepływają od obiektu źródłowego do obiektu docelowego.

Metoda SetBinding zdefiniowana przez klasę BindableObject ma argument typu BindingBase, z którego pochodzi klasa Binding, ale istnieją inne metody SetBinding zdefiniowane przez klasę BindableObjectExtensions. Kod w języku XAML używa prostszej SetBindingBindableObjectExtensions metody rozszerzenia z klasy :

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

Obiekt Label jest obiektem docelowym powiązania, czyli takim, na którym jest ustawiona ta właściwość i na którym jest wywoływana metoda. Właściwość BindingContext wskazuje obiekt źródłowy powiązania, którym jest obiekt Slider. Metoda SetBinding jest wywoływana w obiekcie docelowym powiązania, ale określa zarówno właściwość obiektu docelowego, jak i właściwość obiektu źródłowego. Właściwość obiektu docelowego jest określona jako obiekt BindableProperty: Label.RotationProperty. Właściwość obiektu jest określona jako ciąg i wskazuje właściwość Value obiektu Slider.

Ważne

Właściwość obiektu docelowego musi być oparta na właściwości, którą można powiązać. W związku z tym obiekt docelowy musi być wystąpieniem klasy, która pochodzi z BindableObjectklasy . Aby uzyskać więcej informacji, zobacz Właściwości możliwe do powiązania.

Właściwość źródłowa jest określana jako ciąg. Wewnętrznie do uzyskania dostępu do rzeczywistej właściwości służy odbicie. Jednak w tym konkretnym przypadku właściwość Value jest również oparta na właściwości, którą można powiązać.

Manipulowanie obiektem Slider powoduje obracanie odpowiednio obiektu Label:

Basic code binding.

Alternatywnie można określić powiązanie danych w języku XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Tak samo jak w kodzie powiązanie danych jest ustawiane na obiekcie docelowym, którym jest obiekt Label. Do zdefiniowania powiązania danych służą dwa rozszerzenia znaczników XAML:

  • Rozszerzenie struktury znaczników x:Reference jest wymagane, aby można było odwoływać się do obiektu źródłowego, którym jest obiekt Slider o nazwie slider.
  • Rozszerzenie struktury znaczników Binding łączy właściwość Rotation obiektu Label z właściwością Value obiektu Slider.

Aby uzyskać więcej informacji na temat rozszerzeń znaczników XAML, zobacz Korzystanie z rozszerzeń znaczników XAML.

Uwaga

Właściwość źródłowa jest określana z Path właściwością Binding rozszerzenia znaczników, która odpowiada Path właściwości klasy Binding .

Rozszerzenia struktury znaczników XAML, takie jak x:Reference i Binding, mogą mieć zdefiniowane atrybuty właściwości zawartości, co w przypadku rozszerzeń struktury znaczników XAML oznacza, że nazwa właściwości nie musi być widoczna. Właściwość Name jest właściwością zawartości rozszerzenia x:Reference, a właściwość Path jest właściwością zawartości rozszerzenia Binding, co oznacza, że można je wyeliminować z wyrażeń:

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

Powiązania bez kontekstu powiązania

Właściwość BindingContext jest ważnym składnikiem powiązań danych, ale nie zawsze jest niezbędna. Obiekt źródłowy można zamiast tego określić w wywołaniu SetBinding lub Binding rozszerzeniu znaczników:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

W tym przykładzie Slider element jest zdefiniowany w celu kontrolowania Scale właściwości .Label Z tego powodu Slider parametr jest ustawiony dla zakresu od -2 do 2.

Plik za kodem ustawia powiązanie z SetBinding metodą , a drugi argument jest konstruktorem klasy Binding :

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

Konstruktor Binding ma 6 parametrów, dlatego parametr source jest określony za pomocą nazwanego argumentu. Argumentem jest obiekt slider.

Uwaga

Klasa VisualElement definiuje również właściwości ScaleX i ScaleY, które umożliwiają skalowanie klasy VisualElement w różny sposób poziomo i pionowo.

Alternatywnie można określić powiązanie danych w języku XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

W tym przykładzie Binding rozszerzenie znaczników ma dwa zestawy właściwości i SourcePath, rozdzielone przecinkami. Właściwość Source jest ustawiona na osadzone rozszerzenie struktury znaczników x:Reference, które w przeciwnym razie ma taką samą składnię jak ustawienie właściwości BindingContext.

Właściwością zawartości rozszerzenia struktury znaczników Binding jest właściwość Path, ale fragment Path= rozszerzenia struktury znaczników można wyeliminować tylko wtedy, gdy jest to pierwsza właściwość w wyrażeniu. Aby wyeliminować fragment Path=, musisz zamienić miejscami obie właściwości:

Scale="{Binding Value, Source={x:Reference slider}}" />

Chociaż rozszerzenia struktury znaczników XAML są zwykle ograniczone przez nawiasy klamrowe, można je również wyrazić w postaci elementów obiektów:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

W tym przykładzie Source właściwości i Path są zwykłymi atrybutami XAML. Wartości są wyświetlane w cudzysłowie, a atrybuty nie są oddzielone przecinkiem. Rozszerzenie struktury znaczników x:Reference może również stać się elementem obiektu:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

Ta składnia nie jest typowa, ale czasami jest niezbędna, gdy używane są obiekty złożone.

W pokazanych do tej pory przykładach dla właściwości BindingContext i właściwości Source klasy Binding jest ustawione rozszerzenie struktury znaczników x:Reference, aby można było odwoływać się do innego widoku na stronie. Te dwie właściwości są typu Object i można je ustawić na dowolny obiekt, który zawiera właściwości odpowiednie dla obiektów źródłowych powiązania. Można również ustawić BindingContext właściwość lub Source na x:Static rozszerzenie znaczników w celu odwołowania się do wartości właściwości statycznej lub pola albo StaticResource rozszerzenia znaczników w celu odwołania się do obiektu przechowywanego w słowniku zasobów lub bezpośrednio do obiektu, który jest często wystąpieniem modelu viewmodel.

Uwaga

Właściwość BindingContext można również ustawić na obiekt Binding, aby właściwości Source i Path rozszerzenia Binding definiowały kontekst powiązania.

Dziedziczenie kontekstu powiązania

Obiekt źródłowy można określić przy użyciu BindingContext właściwości lub Source właściwości Binding obiektu. Jeśli ustawione są obie, właściwość Source obiektu Binding ma pierwszeństwo przed właściwością BindingContext.

Ważne

Wartość BindingContext właściwości jest dziedziczona za pomocą drzewa wizualnego.

W poniższym przykładzie XAML pokazano dziedziczenie kontekstu powiązania:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">
        <StackLayout VerticalOptions="Fill"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="End"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="Start"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />
    </StackLayout>
</ContentPage>

W tym przykładzie BindingContext właściwość obiektu StackLayout jest ustawiona slider na obiekt . Ten kontekst powiązania jest dziedziczony zarówno przez właściwość Label, jak i właściwość BoxView, których właściwości Rotation są ustawione na właściwość Value obiektu Slider:

Binding context inheritance.