TOC

This article has been localized into Polish by the community.

Powiązanie danych:

Konwersja wartości za pomocą IValueConverter

Do tej pory zastosowaliśmy kilka prostych powiązań, kiedy to typy danych wysyłanych i odbieranych były zawsze ze sobą kompatybilne. Jednak spotkasz się z wieloma przypadkami, gdy dane konkretnego typu trzeba będzie zaprezentować w nieco inny sposób.

Kiedy stosujemy konwerter wartości?

Konwertery wartości są bardzo często używane przy wiązaniu danych. Oto kilka podstawowych przykładów:

  • Masz wartość liczbową, ale chciałbyś pokazać wartość zero w jednych przypadkach, a liczby dodatnie w pozostałych
  • Chciałbyś zaznaczyć CheckBox na podstawie wartości zmiennej, ale ta wartość jest tekstem np. "tak" lub "nie", a nie wartością typu Boolean (true/false).
  • Masz wielkość pliku wyrażoną w bajtach, ale chciałbyś ją pokazać w bajtach, kilobajtach, megabajtach lub gigabajtach, w zależności od jej wielkości

Jest to kilka prostych przypadków, ale może być ich zdecydowanie więcej. Na przykład chcesz ustawić zaznaczenie kontrolki CheckBox na podstawie zmiennej typu Boolean, ale na odwrót - to znaczy chciałbyś, aby CheckBox był zaznaczony, gdy zmienna jest równa "false", a niezaznaczony, gdy zmienna jest równa "true". Mógłbyś nawet wykorzystać konwerter do wygenerowania obrazka i ustawienia go w ImageSource w zależności od wartości zmiennej. Na przykład sygnał zielony dla wartości "true" i czerwony dla "false". Możliwości są praktycznie nieograniczone!

W takich przypadkach możesz zastosować konwerter wartości. Te niewielkie klasy, które implementują interfejs IValueConverter, będą działać jak pośrednicy i tłumaczyć wartości między źródłem a miejscem docelowym. We jakichkolwiek przypadkach, gdy potrzebujesz dokonać transformacji danych w jedną lub w drugą stronę - najprawdopodobniej potrzebujesz konwertera.

Implementacja prostego konwertera wartości

Jak wspomniano wcześniej - konwerter wartości WPF wymaga zaimplementowania interfejsu IValueConverter lub alternatywnie interfejsu IMultiValueConverter (więcej o nim powiemy później). Oba interfejsy wymagają tylko zaimplementowania dwóch metod: Convert() i ConvertBack(). Jak sama nazwa wskazuje, te metody będą używane do konwersji wartości do docelowego formatu oraz w drugą stronę - do formatu źródłowego.

Spróbujmy teraz zaimplementować prosty konwerter, który przekształci wartość tekstową na wartość Boolean i odwrotnie. Jeśli jesteś początkujący w WPF (a pewnie tak jest, skoro czytasz ten kurs) możesz nie znać wszystkich pojęć użytych w tym przykładzie, ale nie martw się - wszystkie zostaną wyjaśnione w kolejnej części za kodem:

<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";
		}
	}
}

Kod C# (Code-behind)

Przeanalizujmy teraz kod z przykładu. Zaimplementowaliśmy konwerter wartości w klasie YesNoToBooleanConverter, która ma dwie metody: Convert() i ConvertBack(), wymagane przez interfejs IValueConverter. Metoda Convert() zakłada, że na wejściu otrzyma zmienną typu string (parametr o nazwie value) i konwertuje ją na typ Boolean ("true" lub "false") z domyślną wartością równą "false". Dla zabawy dodałem również konwersję z języka francuskiego.

Oczywiście metoda ConvertBack() wykonuje pracę odwrotną: zakłada ona, że otrzyma w parametrze wejściowym wartość typu Boolean i zwróci angielskie słowo "yes" lub "no", z domyślną wartością równą "no".

Możesz się zastanawiać, do czego służą pozostałe parametry w tych dwóch metodach, ale w tym przykładzie nie są one potrzebne. Wykorzystamy je w kolejnych rozdziałach, gdzie zostaną dokładnie omówione.

XAML

W części XAML programu zaczynamy od deklaracji instancji naszego konwertera jako zasoby okna (Window.Resources). Następnie mamy kontrolkę TextBox, jedną parę kontrolek TextBlock i jeden CheckBox. I to jest to miejsce, w którym dzieją się najciekawsze rzeczy: łączymy tu zawartość kontrolki TextBox z kontrolką TextBlock oraz z kontrolką CheckBox z wykorzystaniem właściwości "Converter" i referencji do naszego konwertera. Dzięki temu wartości tekstowe będą zamieniane na logiczne i z powrotem, w zależności co jest potrzebne.

Po uruchomieniu tego przykładu będziesz mieć możliwość zmiany wartości w dwóch miejscach: wpisując "yes" do kontrolki TextBox, jeśli chcesz otrzymać po konwersji "true" lub jakiekolwiek inne słowo, jeśli chcesz otrzymać "false" - lub przez zmianę wyboru w kontrolce CheckBox. W zależności, którą kontrolkę zmienisz, będzie to miało wpływ na wartości w pozostałych kontrolkach.

Podsumowanie

Jest to przykład na proste zastosowanie konwertera wartości. Przykład jest nieco dłuży, niż było to zamierzone, ale wszystko w celu lepszego wyjaśnienia tematu. W kolejnym rozdziale zajmiemy się bardziej rozbudowanym przykładem, ale zanim zasiądziesz do napisania własnego konwertera, poszukaj czy przypadkiem WPF już takiego nie zawiera. W chwili pisania tego tekstu w WPF jest ponad 20 wbudowanych konwerterów, które możesz wykorzystać, ale musisz poznać ich nazwy. Znalazłem następująca listę, która może ci się przydać: http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!