This article has been localized into German by the community.
A special thanks goes out to user #371 for the German translation of this article: Heinz Kessler
Wertumwandlung mit IValueConverter
Bisher haben wir einige einfache Datenbindungen verwendet, bei denen die sendende und die empfangende Eigenschaft immer kompatibel waren. Sie werden jedoch bald in Situationen geraten, in denen Sie einen gebundenen Wert eines bestimmten Typs verwenden und ihn dann ein bisschen anders darstellen wollen.
Wann ein Wert-Konverter benutzt werden soll
Wert-Konverter werden sehr oft zusammen mit Datenbindungen benutzt. Hier ein paar einfache Beispiele:
- Sie haben einen numerischen Wert, aber sie möchten Nullwerte anders darstellen als positive Werte.
- Sie möchten eine CheckBox ankreuzen oder nicht, aber der Wert ist eine Zeichenkette wie "Ja" und "Nein", anstatt eines bool-Wertes.
- Sie haben eine Dateigröße in Bytes, aber Sie möchten sie in Bytes, Kilobytes, Megabytes oder Gigabytes anzeigen, je nachdem, wie groß der Wert ist.
Dies sind einige der einfachen Fälle, aber es gibt noch viel mehr. Beispielsweise können Sie eine CheckBox basierend auf einem booleschen Wert markieren, aber Sie möchten es umkehren, so dass das CheckBox angehakt wird, wenn der Wert falsch ist, und nicht, wenn der Wert wahr ist. Sie können sogar einen Konverter verwenden, um ein Bild für eine ImageSource zu erzeugen, basierend auf dem Wert, wie ein grünes Zeichen für true oder ein rotes Zeichen für false - die Möglichkeiten sind nahezu unbegrenzt!
Für solche Fälle können Sie einen Wertekonverter verwenden. Diese kleinen Klassen, die das IValueConverter Interface implementieren, agieren wie Zwischenhändler und übersetzen einen Wert zwischen der Quelle und dem Ziel. In jeder Situation, in der Sie einen Wert transformieren müssen, bevor er sein Ziel erreicht oder wieder zu seiner Quelle zurückkehrt, benötigen Sie wahrscheinlich einen Konverter.
Implementierung eines einfachen Wert-Konverters
Wie bereits erwähnt, muss ein WPF-Wertkonverter die IValueConverter-Schnittstelle oder alternativ die IMultiValueConverter-Schnittstelle implementieren (mehr dazu später). Für beide Interfaces müssen Sie lediglich zwei Methoden implementieren: Convert() und ConvertBack(). Wie der Name schon sagt, werden diese Methoden verwendet, um den Wert in das Zielformat zu konvertieren und dann wieder zurück.
Lassen Sie uns einen einfachen Konverter implementieren, der einen String als Eingabe nimmt und dann einen booleschen Wert zurückgibt, sowie umgekehrt. Wenn Sie neu bei WPF sind, und das sind Sie wahrscheinlich, da Sie dieses Tutorial lesen, dann kennen Sie vielleicht nicht alle der im Beispiel verwendeten Konzepte, aber keine Sorge, sie werden später noch alle erklärt werden, nach diesem Listing:
<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
Title="ConverterSample" Height="140" Width="250">
<Window.Resources>
<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
</Window.Resources>
<StackPanel Margin="10">
<TextBox Name="txtValue" />
<WrapPanel Margin="0,10">
<TextBlock Text="Current value is: " />
<TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
</WrapPanel>
<CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Data;
namespace WpfTutorialSamples.DataBinding
{
public partial class ConverterSample : Window
{
public ConverterSample()
{
InitializeComponent();
}
}
public class YesNoToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch(value.ToString().ToLower())
{
case "yes":
case "oui":
return true;
case "no":
case "non":
return false;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value is bool)
{
if((bool)value == true)
return "yes";
else
return "no";
}
return "no";
}
}
}
Code-behind
Also, fangen wir von hinten an und arbeiten uns dann durch das Beispiel. Wir haben einen Konverter in der Code-behind-Datei namens YesNoToBooleanConverter implementiert. Wie angekündigt, implementiert er nur die beiden benötigten Methoden, Convert() und ConvertBack(). Die Convert()-Methode geht davon aus, dass sie einen String als Eingabe (den value-Parameter) erhält und diesen dann in einen booleschen wahren oder falschen Wert mit einem Ersatz-Wert von false umwandelt. Zum Spaß habe ich die Möglichkeit hinzugefügt, diese Konvertierung auch von französischen Wörtern durchzuführen.
Die ConvertBack() Methode macht offensichtlich das Gegenteil: Er nimmt einen Eingabewert mit einem booleschen Typ an und gibt dann das englische Wort "yes" oder "no" zurück, mit einem Ersatz-Wert von "no".
Sie werden sich vielleicht fragen, welche zusätzlichen Parameter diese beiden Methoden brauchen, aber sie werden in diesem Beispiel keine benötigen. Wir werden sie in einem der nächsten Kapitel verwenden, wo sie erklärt werden.
XAML
Im XAML-Teil des Programms deklarieren wir zunächst eine Instanz unseres Konverters als Ressource für das Fenster. Wir haben dann eine TextBox, ein paar TextBlocks und ein CheckBox-Steuerelement und hier wird es interessant: Wir binden den Wert der TextBox an das TextBlock- und das CheckBox-Steuerelement und jonglieren mit der Converter-Eigenschaft und unserer eigenen Konverterreferenz zwischen einem String und einem booleschen Wert, je nachdem, was benötigt wird.
Wenn Sie versuchen, dieses Beispiel auszuführen, können Sie den Wert an zwei Stellen ändern: Indem Sie "yes" in die TextBox schreiben (oder einen anderen Wert, wenn Sie 'false' wollen) oder indem Sie die CheckBox anhaken. Egal was Sie tun, die Änderung wird sowohl im anderen Steuerelement als auch im TextBlock wiedergegeben.
Zusammenfassung
Dies war ein Beispiel für einen einfachen Wert-Konverter, das etwas länger als üblich wurde, um das Konzept zu veranschaulichen. Im nächsten Kapitel werden wir uns ein weiterführendes Beispiel ansehen, aber bevor Sie Ihren eigenen Konverter schreiben, sollten Sie vielleicht überprüfen, ob WPF bereits einen für diesen Zweck enthält. Als dieser Artikel geschrieben wurde, gab es mehr als 20 eingebaute Konverter, die Sie nutzen können, aber Sie müssen ihre Namen kennen. Ich habe folgende Liste gefunden, die für Sie nützlich sein könnte: http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters