Bindungsmodus
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:
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 ZielOneWay
– Daten fließen von der Quelle zum ZielOneWayToSource
– Daten fließen vom Ziel zur QuelleOneTime
– Daten werden von der Quelle zum Ziel übertragen, aber nur, wenn sich derBindingContext
ändert
Bidirektionale Bindungen
Die meisten bindbaren Eigenschaften haben einen Standardbindungsmodus von OneWay
, aber einige Eigenschaften haben einen Standardbindungsmodus von TwoWay
, darunter die folgenden:
- die
Date
-Eigenschaft von DatePicker - die
Text
-Eigenschaft von Editor, Entry, SearchBar und EntryCell - die
IsRefreshing
-Eigenschaft von ListView - die
SelectedItem
-Eigenschaft vonMultiPage
- die Eigenschaften
SelectedIndex
undSelectedItem
von Picker - die
Value
-Eigenschaft von Slider und Stepper - die
IsToggled
-Eigenschaft von Switch - die
On
-Eigenschaft von SwitchCell - die
Time
-Eigenschaft von TimePicker
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 BindingMode
OneTime
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:
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.