TOC

This article has been localized into Russian by the community.

Связывание данных:

Конвертор значений IValueConverter

До сих пор мы использовали некоторые простые привязки данных, где отправляющее и принимающее свойства были всегда совместимы. Тем не менее, рано или поздно вы столкнетесь с ситуациями, когда вы захотите использовать связывание для одного типа, а представлять его другим.

Когда использовать конверторы значений

Преобразователи значений используются со связыванием данных очень часто. Вот несколько примеров:

  • У вас есть численное значение, и вы хотите показывать нулевые и положительные номера разным способом.
  • Вы хотите, чтобы значения Checkbox принимали значения "yes" или "no" вместо стандартных значений Boolean.
  • Вы хотите, чтобы размер файла отображался в байта, килобайтах, мегабайтах или гигабайтах в зависимости от его размера.

Есть как простые случаи, так и более сложные. Например, вы хотите проверять Checkbox, основанный на значениях Boolean, но в инвертированном виде. Т.е. так, чтобы выбранный Checkbox соответствовал значению false, а не выбранный значению true. Вы так же можете использовать конвертер, чтобы генерировать изображения для ImageSource, исходя из их значения: зелёный для true и красный для false. Возможные применения безграничны.

В подобных случаях вы можете использовать конверторы значений. Это небольшие классы, которые реализуют интерфейс IValueConverter, который действует, как промежуточное звено, переводчик значений для отправителя и приёмника. Таким образом, в любых ситуациях, когда вам нужно преобразовать значения перед тем как они будут получены приёмником или в обратном направлении, вам нужен конвертер.

Реализация простого конвертора значений

Как упоминалось ранее, конвертор значений для WPF должен реализовать интерфейс IValueConverter или IMultiValueConverter (об этом будет рассказано чуть дальше). Оба интерфейса требуют, чтобы вы реализовали два метода: Convert() и ConvertBack(). Как можно понять из названий методов, эти методы используются для преобразования значений для прёмника и обратно.

Давайте реализуем простой конвертор, который принимает на вход строку string и затем возвращает значение Boolean и обратно. Если вы новичёк в WPF, и ещё не успели изучить всего описанного в этом руководстве, не беспокойтесь, они будут объяснены позднее:

<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

Итак, давайте начнём с конца и пройдём по всему примеру. Мы реализовали конвертер в Code-behind файле и назвали его YesNoToBooleanConverter. Как ранее говорилось, он реализует два метода: Convert() и ConvertBack(). Метод Convert() предполагает получение на вход строки string (параметр value) и заетм преобразует его в значение Boolean true или false. Для интереса я добавил возможность делать преобразование и на французском языке.

Метод ConvertBack() очевидно делает обратное: принимает на вход значения Boolean и возвращает английские слова "yes" или "no". В случае ошибки возвращается слово "no".

Вас могут удивить дополнительные параметры, которые принимают эти два метода, но они не нужны в этом примере. Мы будем использовать их в следующих главах, где они и будут объяснены.

XAML

XAML часть программы мы начнём с объявления экземпляра нашего конвертора как ресурса для window. У нас есть TextBox, парочка TextBlocks и Checkbox. Именно в нём и будет самое интересное: мы привяжем значение TextBox к TextBlock и Checkbox контролам используя свойство Converter со ссылкой на наш собственный конвертер. Мы будем преобразовывать значения туда и обратно из string в Boolean в зависимости от того, что нам надо.

Если вы попробуете запустить этот примере, вы сможете изменять значения в двух местах: писать слово "yes" в TexBox для true (или любое другое, чтобы получить false) или выбирать Checkbox. Не важно, что вы сделаете. Изменения будут отображены в контролах TextBlock.

Заключение

Это был пример простого конвертора значений, сделанного по большей части ради демонстрационных целей. В следующей главе вы увидете более продвинутый пример. Но перед тем как вы пойдёте писать свой собственный конвертер убедитесь, пожалуйста, что WPF нет уже реализованного конвертора нужного типа. Как мы уже писали, вы можете воспользоваться возможностями более 20 встроенных конверторов, но нужно знать их названия. Я нашёл для вас такой список с указанием их названий: 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!