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

Последнее обновление: 11.02.2016

Конвертеры значений (value converter) позволяют преобразовать значения, приходящие от источника привязки, к тому типу, который понятен приемнику привязки. Не всегда два связываемых привязкой свойства могут иметь совместимые типы. И в этом случае как раз и нужен конвертер значений.

Возьмем, к примеру, привязку элемента DatePicker к TextBlock. Допустим, мы хотим вывести выбранную дату в текстовое поле. Зная основы привязки, мы бы сделали так:

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <DatePicker x:Name="calendar" />
    <TextBlock Text="{Binding ElementName=calendar, Path=Date}" />
</StackPanel>

Однако практического результата мы бы не получили:

Все потому что свойство Date объекта DatePicker представляет объект DateTimeOffset, и система просто не знает, как его преобразовать в строку. В этом случае нам как раз понадобится конвертер значений.

Теперь добавим в проект следующий класс:

using System;
using Windows.UI.Xaml.Data;

public class DateTimeOffsetToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        DateTimeOffset sourceTime = (DateTimeOffset)value;
        DateTime targetTime = sourceTime.DateTime;
        return targetTime.ToString("dd.MM.yyyy");
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        DateTimeOffset resultTime = DateTime.Parse(value.ToString());
        return resultTime;
    }
}

Конвертер значений должен реализовать интерфейс Windows.UI.Xaml.Data.IValueConverter. В нем определяюся два метода: Convert() (преобразует значение от источника привязки в тип, понятный для приемника привязки) и ConvertBack() (выполняет противоположную операцию). Оба метода принимают следующие параметры:

  • object value: значение, которое надо преобразовать

  • Type targetType: тип, к которому надо преобразовать значение value

  • object parameter: вспомогательный параметр привязки

  • string language: языковой код текущей культуры, например, "en-US"

В нашем конвертере значений метод Convert возвращает строковое представление даты в формате "dd.MM.yyyy". То есть мы ожидаем, что в качестве параметра value будет передаваться объект DateTimeOffset.

Метод ConvertBack выполняет обратное преобразование - из строки в DateTimeOffset.

Используем наш конвертер в xaml:

<Page
    x:Class="BindingApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BindingApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <local:DateTimeOffsetToStringConverter x:Key="myDateConverter" />
    </Page.Resources>
    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <DatePicker x:Name="calendar" />
        <TextBlock Text="{Binding ElementName=calendar, Path =Date,Converter={StaticResource myDateConverter}}" />
    </StackPanel>
</Page>

Здесь объект конвертера значений задан как ресурс. Чтобы применить этот конвертер в конструкции привязки используется параметр Converter с ссылкой на ресурс: Converter={StaticResource myDateConverter}

И теперь текстовый блок будет выводить дату как и должен:

Конвертер значений в Universal Windows Platform

Кроме конвертера мы также можем использовать параметры ConverterParameter и ConverterLanguage. В конвертере значений это соответственно параметры object parameter и string language. Применим их, изменим код конвертера:

public class DateTimeOffsetToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        DateTimeOffset sourceTime = (DateTimeOffset)value;
        DateTime targetTime = sourceTime.DateTime;
        string result = targetTime.ToString("dd.MM.yyyy");
        // проверяем язык
		if (language == "en-US")
            result = targetTime.ToString("MM-dd-yyyy");
        // проверяем переданный параметр
		if (parameter!=null && parameter.ToString() == "full")
            result = "Сегодня: " + result;
        
		return result;
    }

	public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        DateTimeOffset resultTime = DateTime.Parse(value.ToString());
        return resultTime;
    }
}

В качестве параметра может передаваться любой объект. Если параметр в xaml не используется, то передается null. В данном случае мы проверяем, равен ли параметр строке "full", то есть мы ожидаем, что параметр будет передавать строковое значение. И если равен, то добавляем к дате строку "Сегодня". Также если язык имеет код "en-US", то возвращает дату в другом формате.

Для применения параметра изменим код xaml:

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <DatePicker x:Name="calendar" />
    
	<TextBlock Text="{Binding ElementName=calendar, Path=Date, 
        Converter={StaticResource myDateConverter}}" />
		
    <TextBlock Text="{Binding ElementName=calendar, Path=Date, 
        Converter={StaticResource myDateConverter}, 
        ConverterParameter=full, ConverterLanguage=en-US}" />
</StackPanel>
Value Converter в UWP
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850