Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
.NET Multi-platform App UI (.NET MAUI)-Datenbindungen übertragen in der Regel Daten aus einer Quelleigenschaft in eine Zieleigenschaft und in einigen Fällen von der Zieleigenschaft in die Quelleigenschaft. Diese Übertragung ist einfach, wenn die Quell- und Zieleigenschaften denselben Typ aufweisen oder wenn ein Typ über eine implizite Konvertierung in den anderen Typ konvertiert werden kann. Wenn dies nicht der Fall ist, muss eine Typkonvertierung erfolgen.
Im Artikel zur Zeichenfolgenformatierung haben Sie gesehen, wie Sie die StringFormat Eigenschaft einer Datenbindung verwenden können, um einen beliebigen Typ in eine Zeichenfolge zu konvertieren. Für andere Arten von Konvertierungen müssen Sie speziellen Code in einer Klasse schreiben, die die IValueConverter Schnittstelle implementiert. Klassen, die IValueConverter implementieren, werden als Wertkonverter bezeichnet, aber sie werden auch häufig als Bindungskonverter oder Bindungswertkonverter bezeichnet.
Bindungswertkonverter
Angenommen, Sie möchten eine Datenbindung definieren, in der die Quelleigenschaft vom Typ int ist, aber die Zieleigenschaft ist eine bool. Sie möchten, dass diese Datenbindung einen false Wert erzeugt, wenn die ganzzahlige Quelle gleich 0 ist, andernfalls true . Dies kann mit einer Klasse erreicht werden, die die IValueConverter Schnittstelle implementiert:
public class IntToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value != 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? 1 : 0;
}
}
Anschließend legen Sie eine Instanz dieser Klasse auf die Converter Eigenschaft der Binding Klasse oder auf die Converter Eigenschaft der Binding Markuperweiterung fest. Diese Klasse wird Teil der Datenbindung.
Die Convert Methode wird aufgerufen, wenn Daten aus der Quelle in das Ziel in OneWay oder TwoWay Bindungen verschoben werden. Der value Parameter ist das Objekt oder der Wert aus der Datenbindungsquelle. Die Methode muss einen Wert des Typs des Datenbindungsziels zurückgeben. Die hier gezeigte Methode wandelt den value Parameter in einen int und vergleicht ihn dann mit 0 für einen bool Rückgabewert.
Die ConvertBack Methode wird aufgerufen, wenn Daten vom Ziel in die Quelle in TwoWay oder OneWayToSource Bindungen verschoben werden.
ConvertBack führt die entgegengesetzte Konvertierung aus: Es wird davon ausgegangen, dass der value Parameter vom bool Ziel stammt, und konvertiert ihn in einen int Rückgabewert für die Quelle.
Hinweis
Wenn eine Datenbindung auch eine StringFormat Einstellung enthält, wird der Wertkonverter aufgerufen, bevor das Ergebnis als Zeichenfolge formatiert wird.
Im folgenden Beispiel wird die Verwendung dieses Wertkonverters in einer Datenbindung veranschaulicht:
<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.EnableButtonsPage"
Title="Enable Buttons">
<ContentPage.Resources>
<local:IntToBoolConverter x:Key="intToBool" />
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<Entry x:Name="entry1"
Text=""
Placeholder="enter search term"
VerticalOptions="Center" />
<Button x:DataType="Entry"
Text="Search"
HorizontalOptions="Center"
VerticalOptions="Center"
IsEnabled="{Binding Source={x:Reference entry1},
Path=Text.Length,
Converter={StaticResource intToBool}}" />
<Entry x:Name="entry2"
Text=""
Placeholder="enter destination"
VerticalOptions="Center" />
<Button x:DataType="Entry"
Text="Submit"
HorizontalOptions="Center"
VerticalOptions="Center"
IsEnabled="{Binding Source={x:Reference entry2},
Path=Text.Length,
Converter={StaticResource intToBool}}" />
</StackLayout>
</ContentPage>
In diesem Beispiel wird das IntToBoolConverter im Ressourcenwörterbuch der Seite instanziiert. Anschließend wird mit einer StaticResource Markuperweiterung verwiesen, um die Converter Eigenschaft in zwei Datenbindungen festzulegen. Es ist sehr üblich, Datenkonverter für mehrere Datenbindungen auf der Seite freizugeben. Wenn ein Wertkonverter auf mehreren Seiten Ihrer Anwendung verwendet wird, können Sie ihn im Ressourcenverzeichnis auf Anwendungsebene instanziieren.
In diesem Beispiel wird eine häufige Notwendigkeit veranschaulicht, wenn ein Button Vorgang auf der Grundlage von Text ausgeführt wird, den der Benutzer in eine Entry Ansicht eingibt. Die Text Eigenschaft jeder Entry wird in eine leere Zeichenfolge initialisiert, da die Text Eigenschaft standardmäßig ist null und die Datenbindung in diesem Fall nicht funktioniert. Wenn nichts in Entry eingetragen wurde, sollte Button deaktiviert werden. Jede Button enthält eine Datenbindung für ihre IsEnabled Eigenschaft. Die Datenbindungsquelle ist die Eigenschaft Length der Eigenschaft Text des entsprechenden Entry. Wenn diese Length Eigenschaft nicht 0 ist, wird true vom Wertkonverter zurückgegeben und Button wird aktiviert.
Hinweis
Wenn Sie wissen, dass ein Wertkonverter nur in OneWay Bindings verwendet wird, kann die Methode ConvertBack einfach null zurückgeben.
Die Convert oben gezeigte Methode geht davon aus, dass das value Argument vom Typ int ist und der Rückgabewert vom Typ boolsein muss. Ebenso geht die ConvertBack Methode davon aus, dass das value Argument vom Typ bool ist und der Rückgabewert lautet int. Wenn dies nicht der Fall ist, tritt eine Laufzeit-Ausnahme auf.
Sie können Wertkonverter schreiben, um generalisierter zu werden und mehrere verschiedene Datentypen zu akzeptieren. Die Methoden Convert und ConvertBack können entweder die Operatoren as oder is mit dem Parameter value verwenden oder GetType auf diesen Parameter anwenden, um dessen Typ zu ermitteln und dann entsprechend zu handeln. Der erwartete Typ des Rückgabewerts jeder Methode wird vom targetType Parameter angegeben. Manchmal werden Wertkonverter mit Datenbindungen unterschiedlicher Zieltypen verwendet. In diesem Fall kann der Wertkonverter das targetType Argument verwenden, um eine Konvertierung für den richtigen Typ auszuführen.
Wenn die ausgeführte Konvertierung für verschiedene Kulturen unterschiedlich ist, verwenden Sie den culture Parameter für diesen Zweck.
Bindungskonvertereigenschaften
Wertkonverterklassen können Eigenschaften und generische Parameter aufweisen. Der folgende Wertkonverter konvertiert eine bool von der Quelle in ein Objekt vom Typ T für das Ziel.
public class BoolToObjectConverter<T> : IValueConverter
{
public T TrueObject { get; set; }
public T FalseObject { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? TrueObject : FalseObject;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((T)value).Equals(TrueObject);
}
}
Im folgenden Beispiel wird veranschaulicht, wie dieser Konverter verwendet werden kann, um den Wert einer Switch Ansicht anzuzeigen. Obwohl es üblich ist, Wertekonverter als Ressourcen in einem Ressourcenwörterbuch zu instanziieren, zeigt dieses Beispiel eine Alternative. Hier wird jeder Wertkonverter zwischen den Binding.Converter-Eigenschafts-Element-Tags instanziiert. Das x:TypeArguments gibt das generische Argument an, und TrueObject sowie FalseObject werden beide auf Objekte dieses Typs festgelegt.
<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.SwitchIndicatorsPage"
Title="Switch Indicators">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="18" />
<Setter Property="VerticalOptions" Value="Center" />
</Style>
<Style TargetType="Switch">
<Setter Property="VerticalOptions" Value="Center" />
</Style>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<StackLayout Orientation="Horizontal"
VerticalOptions="Center">
<Label Text="Subscribe?" />
<Switch x:Name="switch1" />
<Label>
<Label.Text>
<Binding x:DataType="Switch"
Source="{x:Reference switch1}"
Path="IsToggled">
<Binding.Converter>
<local:BoolToObjectConverter x:TypeArguments="x:String"
TrueObject="Of course!"
FalseObject="No way!" />
</Binding.Converter>
</Binding>
</Label.Text>
</Label>
</StackLayout>
<StackLayout Orientation="Horizontal"
VerticalOptions="Center">
<Label Text="Allow popups?" />
<Switch x:Name="switch2" />
<Label>
<Label.Text>
<Binding x:DataType="Switch"
Source="{x:Reference switch2}"
Path="IsToggled">
<Binding.Converter>
<local:BoolToObjectConverter x:TypeArguments="x:String"
TrueObject="Yes"
FalseObject="No" />
</Binding.Converter>
</Binding>
</Label.Text>
<Label.TextColor>
<Binding x:DataType="Switch"
Source="{x:Reference switch2}"
Path="IsToggled">
<Binding.Converter>
<local:BoolToObjectConverter x:TypeArguments="Color"
TrueObject="Green"
FalseObject="Red" />
</Binding.Converter>
</Binding>
</Label.TextColor>
</Label>
</StackLayout>
<StackLayout Orientation="Horizontal"
VerticalOptions="Center">
<Label Text="Learn more?" />
<Switch x:Name="switch3" />
<Label FontSize="18"
VerticalOptions="Center">
<Label.Style>
<Binding x:DataType="Switch"
Source="{x:Reference switch3}"
Path="IsToggled">
<Binding.Converter>
<local:BoolToObjectConverter x:TypeArguments="Style">
<local:BoolToObjectConverter.TrueObject>
<Style TargetType="Label">
<Setter Property="Text" Value="Indubitably!" />
<Setter Property="FontAttributes" Value="Italic, Bold" />
<Setter Property="TextColor" Value="Green" />
</Style>
</local:BoolToObjectConverter.TrueObject>
<local:BoolToObjectConverter.FalseObject>
<Style TargetType="Label">
<Setter Property="Text" Value="Maybe later" />
<Setter Property="FontAttributes" Value="None" />
<Setter Property="TextColor" Value="Red" />
</Style>
</local:BoolToObjectConverter.FalseObject>
</local:BoolToObjectConverter>
</Binding.Converter>
</Binding>
</Label.Style>
</Label>
</StackLayout>
</StackLayout>
</ContentPage>
In diesem Beispiel wird im letzten der drei Switch und Label Paare das generische Argument auf ein Style gesetzt, und ganze Style Objekte werden für die Werte von TrueObject und FalseObject bereitgestellt. Diese überschreiben den impliziten Stil für Label, der im Ressourcenwörterbuch festgelegt ist, sodass die Eigenschaften in diesem Stil explizit dem Label zugewiesen werden. Das Umschalten von Switch führt dazu, dass die entsprechende Label die Änderung widerspiegelt.
Hinweis
Es ist auch möglich, Trigger zu verwenden, um Änderungen auf der Benutzeroberfläche basierend auf anderen Ansichten zu implementieren. Weitere Informationen finden Sie unter Trigger.
Parameter für Bindungskonverter
Die Binding Klasse definiert eine ConverterParameter Eigenschaft, und die Binding Markuperweiterung definiert auch eine ConverterParameter Eigenschaft. Wenn diese Eigenschaft festgelegt ist, wird der Wert als Convert Argument an die Methoden und ConvertBack an die parameter Methoden übergeben. Selbst wenn die Instanz des Wertkonverters zwischen mehreren Datenbindungen geteilt wird, kann dies ConverterParameter unterschiedlich sein, um unterschiedliche Konvertierungen auszuführen.
Die Verwendung der ConverterParameter Eigenschaft kann mit einem Farbauswahlprogramm veranschaulicht werden. Das folgende Beispiel zeigt die RgbColorViewModel mit drei Eigenschaften des Typs float namens Red, Green und Blue, die zum Erstellen eines Color-Werts verwendet werden.
public class RgbColorViewModel : INotifyPropertyChanged
{
Color color;
string name;
public event PropertyChangedEventHandler PropertyChanged;
public float Red
{
get { return color.Red; }
set
{
if (color.Red != value)
{
Color = new Color(value, color.Green, color.Blue);
}
}
}
public float Green
{
get { return color.Green; }
set
{
if (color.Green != value)
{
Color = new Color(color.Red, value, color.Blue);
}
}
}
public float Blue
{
get { return color.Blue; }
set
{
if (color.Blue != value)
{
Color = new Color(color.Red, color.Green, value);
}
}
}
public Color Color
{
get { return color; }
set
{
if (color != value)
{
color = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Red"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Green"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Blue"));
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"));
}
}
}
}
Die Werte der Eigenschaften Red, Green und Blue können zwischen 0 und 1 liegen. Sie ziehen es jedoch möglicherweise vor, dass die Komponenten als zweistellige Hexadezimalwerte angezeigt werden. Um diese als Hexadezimalwerte in XAML anzuzeigen, müssen sie mit 255 multipliziert, in eine ganze Zahl konvertiert und dann mit einer Spezifikation von "X2" in der StringFormat Eigenschaft formatiert werden. Multiplizieren mit 255 und Konvertieren in eine ganze Zahl können vom Wertkonverter ausgeführt werden. Um den Wertkonverter so generalisiert wie möglich zu machen, kann der Multiplikationsfaktor mit der ConverterParameter Eigenschaft angegeben werden, was bedeutet, dass er als Argument die Convert folgenden Methoden ConvertBackparameter eingibt:
public class FloatToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)Math.Round((float)value * GetParameter(parameter));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value / GetParameter(parameter);
}
double GetParameter(object parameter)
{
if (parameter is float)
return (float)parameter;
else if (parameter is int)
return (int)parameter;
else if (parameter is string)
return float.Parse((string)parameter);
return 1;
}
}
In diesem Beispiel wandelt die Methode Convert von einem float zu einem int, während es mit dem parameter-Wert multipliziert. Die ConvertBack Methode dividiert das ganzzahlige value Argument durch parameter und gibt ein float Ergebnis zurück.
Der Typ des parameter Arguments ist wahrscheinlich unterschiedlich, je nachdem, ob die Datenbindung in XAML oder Code definiert ist. Wenn die ConverterParameter Eigenschaft Binding im Code festgelegt ist, wird sie wahrscheinlich auf einen numerischen Wert festgelegt:
binding.ConverterParameter = 255;
Die ConverterParameter Eigenschaft ist vom Typ, Objectsodass der C#-Compiler das Literal 255 als ganze Zahl interpretiert und die Eigenschaft auf diesen Wert festlegt.
In XAML wird dies ConverterParameter jedoch wahrscheinlich wie folgt festgelegt:
<Label Text="{Binding Red,
Converter={StaticResource doubleToInt},
ConverterParameter=255,
StringFormat='Red = {0:X2}'}" />
Während 255 wie eine Zahl aussieht, wird es vom XAML-Parser als eine Zeichenfolge behandelt, weil ConverterParameter vom Typ Object ist. Aus diesem Grund enthält der Wertkonverter eine separate GetParameter Methode, die Fälle vom Typ parameter, float, int oder string behandelt.
Im folgenden XAML-Beispiel wird FloatToIntConverter in seinem Ressourcenwörterbuch instanziiert:
<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.RgbColorSelectorPage"
Title="RGB Color Selector"
x:DataType="local:RgbColorViewModel">
<ContentPage.BindingContext>
<local:RgbColorViewModel Color="Gray" />
</ContentPage.BindingContext>
<ContentPage.Resources>
<Style TargetType="Slider">
<Setter Property="VerticalOptions" Value="Center" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<local:FloatToIntConverter x:Key="floatToInt" />
</ContentPage.Resources>
<StackLayout Margin="20">
<BoxView Color="{Binding Color}"
HeightRequest="100"
WidthRequest="100"
HorizontalOptions="Center" />
<StackLayout Margin="10, 0">
<Label Text="{Binding Name}" />
<Slider Value="{Binding Red}" />
<Label Text="{Binding Red,
Converter={StaticResource floatToInt},
ConverterParameter=255,
StringFormat='Red = {0:X2}'}" />
<Slider Value="{Binding Green}" />
<Label Text="{Binding Green,
Converter={StaticResource floatToInt},
ConverterParameter=255,
StringFormat='Green = {0:X2}'}" />
<Slider Value="{Binding Blue}" />
<Label>
<Label.Text>
<Binding Path="Blue"
StringFormat="Blue = {0:X2}"
Converter="{StaticResource floatToInt}">
<Binding.ConverterParameter>
<x:Single>255</x:Single>
</Binding.ConverterParameter>
</Binding>
</Label.Text>
</Label>
</StackLayout>
</StackLayout>
</ContentPage>
Die Werte der Eigenschaften Red und Green werden mit einer Binding Markierungserweiterung angezeigt. Die Blue Eigenschaft instanziiert die Binding Klasse jedoch, um zu veranschaulichen, wie ein expliziter float Wert auf Eigenschaft ConverterParameter festgelegt werden kann:
Durchsuchen Sie das Beispiel