This article is currently in the process of being translated into Bulgarian (~95% done).
Конвертиране на стойности с IValueConverter
Досега сме използвали някои прости обвързвания на данни, където свойствата за изпращане и получаване винаги са съвместими. Рано или късно ще попаднете в ситуации, в които искате да използвате обвързана стойност от един тип и след това да я представите по малко по-различен начин.
When to use a value converter
Конверторите на стойности се използват много често при обвързването на данни. Ето и някои основни примера:
- Имате числова стойност, но искате да покажете нулевите стойности по един начин, а положителните числа по друг начин
- Искате да поставите отметка в CheckBox на базата на някаква стойност, но стойността е низ като „да“ или „не“ (yes/no) вместо булева стойност
- Имате размер на файл в байтове, но искате да го покажете като байтове, килобайти, мегабайти или гигабайти в зависимост от това колко е голям
Това са някои от простите случаи, но има и много повече. Например, може да искате да поставите отметка в CheckBox въз основа на булева стойност, но искате тя да бъде обърната, така че CheckBox да бъде отметнато, ако стойността е невярна, и да не се проверява, ако стойността е вярна. Можете дори да използвате конвертор, за да генерирате изображение за ImageSource въз основа на стойността, като зелен знак за вярно или червен знак за невярно - възможностите са почти безкрайни!
Именно в такива случаи използвате конвертиране на стойности. Малки класове, които имплементират интерфейса IValueConverter, ще действат като посредници и ще превеждат стойностите между източника и дестинацията. Така във всяка ситуация, в която трябва да преобразувате стойност, преди тя да достигне дестинацията си или да се върне отново към източника си, най-вероятно ще ви е необходим конвертор.
Имплементиране на прост конвертор на стойности
Както споменахме, конверторът на WPF стойност трябва да имплементира интерфейса IValueConverter или в някои случаи интерфейса IMultiValueConverter (повече за него по-късно). И двата интерфейса просто изискват да добавине два метода: Convert() и ConvertBack(). Както подсказват имата, тези методи ще се използват за преобразуване на стойността в целевия формат и след това обратно.
Нека приложим прост конвертор, който приема низ като вход и след това връща булева стойност, както и обратното. Ако сте нов в 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() приема, че получават низ като вход (параметъра value) и след това го преобразуват в булева вярна или невярна стойност (true or false), с резервна стойност false. За по интересно добавих възможността да направя това преобразуване и от френски думи.
Методът ConvertBack() очевидно прави обратното: приема входна стойност с булев тип и след това връща английската дума „yes“ или „no“ в замяна с резервна стойност „no“.
Сигурно са ви странни допълнителните параметри, които тези два метода приемат, но те не са необходими в този пример. Ще ги използваме в някоя от следващите глави, където ще бъдат обяснени.
XAML частта
В XAML частта на програмата започваме с деклариране на инстанция на нашия конвертор като ресурс за прозореца. След това имаме TextBox, няколко TextBlocks и контрола CheckBox и тук се случват интересните неща: свързваме стойността на TextBox с име "txtValue" с TextBlock-а и контролата CheckBox и използвайки свойството Converter и нашия собствен конвертор, ние жонглираме със стойностите напред и назад между низ и булева стойност, в зависимост от това какво е необходимо.
Ако се опитате да изпълните този пример, ще можете да промените стойността на две места: като напишете "yes" в текстовото поле (или всяка друга стойност, ако искате false) или като поставите отметка в квадратчето. Без значение какво правите, промяната ще бъде отразена в другия контрол, както и в TextBlock.
Обобщение
Това беше пример за прост конвертор на стойности, направен малко по-дълъг от необходимото за илюстративни цели. В следващата глава ще разгледаме по-напреднал пример, но преди да започнете да пишете свой собствен конвертор, може да искате да проверите дали WPF вече включва такъв за целта. Към момента на писане на това ръководство има повече от 20 вградени конвертора, от които можете да се възползвате, но трябва да знаете имената им, за да ги ползвате. Намерих следния списък, който може да ви бъде полезен: http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters