Freigeben über


Bindungsmodus

Browse sample.Beispiel ansehen

Jede bindbare Eigenschaft der .NET Multi-Platform App UI (.NET MAUI) hat einen Standardbindungsmodus, der bei der Erstellung der bindbaren Eigenschaft festgelegt wird und der über die DefaultBindingMode-Eigenschaft des BindableProperty-Objekts verfügbar ist. Dieser Standardbindungsmodus gibt den geltenden Modus an, wenn diese Eigenschaft das Ziel einer Datenbindung ist. Der Standardbindungsmodus für die meisten Eigenschaften ist OneWay, z.B. für Rotation, Scale und Opacity. Wenn diese Eigenschaften Ziele von Datenbindungen sind, wird die Zieleigenschaft über die Quelle festgelegt.

Das folgende Beispiel zeigt eine Datenbindung, die für eine Slider definiert ist:

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

In diesem Beispiel ist Label die Quelle für die Datenbindung und Slider das Ziel. Die Bindung verweist auf die Opacity-Eigenschaft des Label, deren Standardwert 1 ist. Daher wird Slider vom ursprünglichen Opacity-Wert von Label auf den Wert 1 initialisiert. Dies ist im folgenden Screenshot zu sehen:

Reverse binding.

Außerdem funktioniert Slider weiterhin. Der Grund dafür ist, dass der Standard-Bindungsmodus für die Value-Eigenschaft von Slider der Modus TwoWay ist. Das bedeutet, dass das Ziel von der Quelle festgelegt wird, wenn die Value-Eigenschaft ein Datenbindungsziel ist, die Quelle aber auch vom Ziel festgelegt wird. Dadurch kann der Slider vom Anfangswert Opacity aus eingestellt werden.

Hinweis

Bindbare Eigenschaften signalisieren eine Eigenschaftsänderung nur, wenn sich die Eigenschaft tatsächlich ändert. Dies verhindert eine Endlosschleife.

Wenn der Standard-Bindungsmodus für die Zieleigenschaft für eine bestimmte Datenbindung nicht geeignet ist, kann er außer Kraft gesetzt werden, indem die Mode-Eigenschaft von Binding (oder die Mode-Eigenschaft der Binding-Markuperweiterung) auf eines der Mitglieder der BindingMode-Enumeration gesetzt wird:

  • Default
  • TwoWay – Daten fließen in beide Richtungen zwischen Quelle und Ziel
  • OneWay – Daten fließen von der Quelle zum Ziel
  • OneWayToSource – Daten fließen vom Ziel zur Quelle
  • OneTime – Daten werden von der Quelle zum Ziel übertragen, aber nur, wenn sich der BindingContext ändert

Bidirektionale Bindungen

Die meisten bindbaren Eigenschaften haben einen Standardbindungsmodus von OneWay, aber einige Eigenschaften haben einen Standardbindungsmodus von TwoWay, darunter die folgenden:

Diese Eigenschaften sind als TwoWay definiert, da bei der Verwendung von Datenbindungen mit dem Model-View-ViewModel (MVVM)-Muster die Viewmodel-Klasse die Datenbindungsquelle ist und die View, die aus Views wie Slider besteht, das Datenbindungsziel ist. MVVM-Bindungen ähneln dem obigen Beispiel, da Sie wahrscheinlich möchten, dass jede Ansicht auf der Seite mit dem Wert der entsprechenden Eigenschaft im Viewmodel initialisiert wird, aber Änderungen in der Ansicht sollten sich auch auf die Viewmodel-Eigenschaft auswirken.

Unidirektionale Bindungen in Richtung der Quelle

Schreibgeschützte bindbare Eigenschaften weisen den Standardbindungsmodus OneWayToSource auf. Die SelectedItem-Eigenschaft von ListView hat zum Beispiel den Standard-Bindungsmodus OneWayToSource Dies liegt daran, dass eine Bindung an die SelectedItem-Eigenschaft zur Einstellung der Bindungsquelle führen sollte.

Einmalige Bindungen

Zieleigenschaften mit dem Bindungsmodus OneTime werden nur dann aktualisiert, wenn der Bindungskontext sich ändert. Für Bindungen dieser Zieleigenschaften vereinfacht das die Bindungsinfrastruktur, weil es nicht erforderlich ist, die Änderungen der Quelleigenschaften zu überwachen.

Einige Eigenschaften wie IsTextPredictionEnabled von Entry nutzen den Standardbindungsmodus OneTime.

Viewmodels und Benachrichtigungen über Eigenschaftsänderungen

Wenn ein Viewmodel in einer Datenbindung verwendet wird, ist das Viewmodel die Datenbindungsquelle. Das Viewmodel definiert keine bindungsfähigen Eigenschaften, aber es implementiert einen Benachrichtigungsmechanismus, mit dem die Bindungsinfrastruktur benachrichtigt werden kann, wenn sich der Wert einer Eigenschaft ändert. Diese Benachrichtigungsmechanismus ist die INotifyPropertyChanged-Schnittstelle, die ein einziges Ereignis mit dem Namen PropertyChanged definiert. Eine Klasse, die diese Schnittstelle implementiert, löst das Ereignis normalerweise aus, wenn sich der Wert einer ihrer öffentlichen Eigenschaften ändert. Das Ereignis muss nicht ausgelöst werden, wenn sich die Eigenschaft nicht ändert. Die INotifyPropertyChanged-Schnittstelle wird auch von BindableObject implementiert, und ein PropertyChanged-Ereignis wird ausgelöst, wenn sich der Wert einer bindbaren Eigenschaft ändert.

Im folgenden Beispiel ermöglicht Ihnen die Datenbindung die Auswahl einer Farbe unter Verwendung von drei Slider-Elementen für den Farbton, die Sättigung und die Leuchtdichte:

public class HslColorViewModel : INotifyPropertyChanged
{
    Color color;
    string name;
    float hue;
    float saturation;
    float luminosity;

    public event PropertyChangedEventHandler PropertyChanged;

    public float Hue
    {
        get
        {
            return hue;
        }
        set
        {
            if (hue != value)
            {
                Color = Color.FromHsla(value, saturation, luminosity);
            }
        }
    }

    public float Saturation
    {
        get
        {
            return saturation;
        }
        set
        {
            if (saturation != value)
            {
                Color = Color.FromHsla(hue, value, luminosity);
            }
        }        
    }

    public float Luminosity
    {
        get
        {
            return luminosity;
        }
        set
        {
            if (luminosity != value)
            {
                Color = Color.FromHsla(hue, saturation, value);
            }
        }
    }

    public Color Color
    {
        get
        {
            return color;
        }
        set
        {
            if (color != value)
            {
                color = value;
                hue = color.GetHue();
                saturation = color.GetSaturation();
                luminosity = color.GetLuminosity();
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));

                Name = NamedColor.GetNearestColorName(color);
            }
        }
    }

    public string Name
    {
        get
        {
            return name;
        }
        private set
        {
            if (name != value)
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }
}

In diesem Beispiel definiert die HslColorViewModel-Klasse die Eigenschaften Hue, Saturation, Luminosity, Color und Name. Wenn sich der Wert einer der drei Farbkomponenten ändert, wird die Color-Eigenschaft neu berechnet, und für alle vier Eigenschaften werden PropertyChanged-Ereignisse werden ausgelöst. Wenn sich die Eigenschaft Color ändert, ruft die statische GetNearestColorName-Methode in der NamedColor-Klasse die nächstgelegene benannte Farbe ab und setzt die Eigenschaft Name.

Wenn ein ViewModel als Bindungsquelle festgelegt wird, fügt die Bindungsinfrastruktur einen Handler an das Ereignis PropertyChanged an. So kann die Bindung informiert werden, wenn sich die Eigenschaften ändern, um die Zieleigenschaften der geänderten Werte entsprechend anzupassen. Wenn die Zieleigenschaft (oder die Binding-Definition einer Zieleigenschaft) jedoch den BindingModeOneTime aufweist, muss die Bindungsinfrastruktur keinen Handler an das PropertyChanged-Ereignis anfügen. Die Zieleigenschaft wird nur dann aktualisiert, wenn sich der BindingContext ändert, und nicht, wenn sich die Quelleigenschaft ändert.

Das folgende XAML verwendet die HslColorViewModel:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.SimpleColorSelectorPage">
    <ContentPage.BindingContext>
        <local:HslColorViewModel Color="MediumTurquoise" />
    </ContentPage.BindingContext>

    <ContentPage.Resources>
        <Style TargetType="Slider">
            <Setter Property="VerticalOptions" Value="CenterAndExpand" />
        </Style>
    </ContentPage.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <BoxView Color="{Binding Color}"
                 Grid.Row="0" />
        <StackLayout Grid.Row="1"
                     Margin="10, 0">
            <Label Text="{Binding Name}"
                   HorizontalTextAlignment="Center" />
            <Slider Value="{Binding Hue}" />
            <Slider Value="{Binding Saturation}" />
            <Slider Value="{Binding Luminosity}" />
        </StackLayout>
    </Grid>
</ContentPage>

In diesem Beispiel wird HslColorViewModel instanziiert und die Eigenschaft Color als BindingContext der Seite definiert. Die Ansichten BoxView, Label und Slider erben den Bindungskontext von ContentPage. Alle diese Ansichten sind Bindungsziele, die auf Quelleneigenschaften des ViewModels verweisen. Für die Eigenschaft Color der BoxView und die Eigenschaft Text der Label sind die Datenbindungen OneWay – die Eigenschaften in der Ansicht werden anhand der Eigenschaften im ViewModel festgelegt. Die Value-Eigenschaft der Slider verwendet jedoch einen TwoWay-Bindungsmodus. Auf diese Weise kann jedes Slider vom ViewMmodel und das ViewModel von jedem Slider festgelegt werden.

Wenn das Beispiel zum ersten Mal ausgeführt wird, werden die BoxView, Label und drei Slider-Elemente auf der Grundlage der ursprünglichen Color-Eigenschaft, die bei der Instanziierung des ViewModels festgelegt wurde, vom Viewmodel gesetzt:

Simple color selector.

Durch Verschieben der Schieberegler werden BoxView und Label entsprechend aktualisiert.

Überschreiben des Bindungsmodus

Der Bindungsmodus für eine Zieleigenschaft kann überschrieben werden, indem Sie die Eigenschaft Mode von Binding (oder die Mode-Eigenschaft der Binding-Markuperweiterung) auf eines der Mitglieder der BindingMode-Enumeration setzen.

Das Setzen der Eigenschaft Mode führt jedoch nicht immer zu dem erwarteten Ergebnis. Im folgenden Beispiel funktioniert das Setzen der Eigenschaft Mode auf TwoWay nicht wie erwartet:

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

Es wird erwartet, dass Slider mit dem Anfangswert der Eigenschaft Scale initialisiert wird, der 1 ist. Wenn eine TwoWay-Bindung initialisiert wird, wird das Ziel zunächst über die Quelle festgelegt, d.h., die Scale-Eigenschaft wird auf den Slider-Standardwert 0 (null) festgelegt. Wenn die TwoWay-Bindung auf dem Slider festgelegt wird, wird der Slider zunächst über die Quelle festgelegt.

Alternativ kann der Bindungsmodus auf OneWayToSource gesetzt werden:

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

Jetzt wird Slider auf 1 initialisiert (der Standardwert von Scale), aber die Manipulation von Slider hat keine Auswirkung auf die Eigenschaft Scale.

Hinweis

Die VisualElement-Klasse definiert auch die Eigenschaften ScaleX und ScaleY, die das VisualElement horizontal und vertikal skalieren können.

Mit der Eigenschaft SelectedItem von ListView kann der Standardbindungsmodus durch einen TwoWay-Bindungsmodus überschrieben werden. Der Standardbindungsmodus ist OneWayToSource. Wenn eine Datenbindung für die SelectedItem-Eigenschaft festgelegt wird, um auf eine Quelleigenschaft in einem ViewModel zu verweisen, dann wird diese Quelleigenschaft von der ListView-Auswahl festgelegt. Unter bestimmten Umständen kann es jedoch auch sinnvoll sein, die ListView vom ViewModel aus zu initialisieren.

Wichtig

Der Standardbindungsmodus kann von Steuerelement zu Steuerelement unterschiedlich sein und wird bei der Erstellung der bindbaren Eigenschaft festgelegt. Er ist über die DefaultBindingMode-Eigenschaft des BindableProperty-Objekts verfügbar.