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

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

Привязка позоляет связать два свойства, которые совпадают по типу данных. Например, свойство Text у класса Entry и свойство Text класса Label представляют тип string. Поэтому тут привязка проходит без проблем. Но в других случаях тип связанных свойств может отличаться. В большинстве случаев инфраструктра Xamarin сама знает, как конвертировать данные простейших типов. Однако в каких-то ситуациях этого оказывается недостаточно, особенно когда необходимо применить к значению привязки дополнительное форматирование.

Например, пусть у нас элемент Label привязан к элементу DatePicker и выводит выбранную дату. По умолчанию дата выводится в формате "MM/dd/yyyy hh:mm:ss". Это не очень удобный формат. Возможно, мы захотим использовать совсем другие форматы.

Для преобразования одного значения к другому в процессе привязки используются пециальные классы - конвертеры значений. К примеру, добавим в наш проект новый класс конвертера значений:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace HelloApp
{
    public class DateTimeToLocalDateConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((DateTime)value).ToString("dd.MM.yyyy");
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DateTime.Now.ToString("dd.MM.yyyy");
        }
    }
}

Прежде всего класс конвертера значений должен реализовать интерфейс IValueConverter. Этот интерфейс определяет два метода: Convert(), который преобразует пришедшее от привязки значение в тот тип, который понимается приемником привязки, и ConvertBack(), который выполняет противоположную операцию.

Оба метода принимают четыре параметра:

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

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

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

  • CultureInfo culture: текущая культура приложения

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

Метод ConvertBack в данном случае не имеет значения, и поэтому он просто возвращает строковое представление текущей даты.

Теперь применим этот конвертер в xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
  <ContentPage.Resources> 
    <ResourceDictionary> 
      <local:DateTimeToLocalDateConverter x:Key="dateConverter" />
    </ResourceDictionary> 
  </ContentPage.Resources>
  <StackLayout>
    <Label Text="{Binding Source={x:Reference Name=datePicker},  Path=Date}" />
    <Label Text="{Binding Source={x:Reference Name=datePicker},  
						Path=Date, 
						Converter={StaticResource dateConverter}}" />
    <DatePicker x:Name="datePicker" Format="D"  />
  </StackLayout>
</ContentPage>

Так как класс конвертера располагается в пространстве имен текущего проекта, то, чтобы класс был доступен в xaml, надо подключить текущее пространство имен.

xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"

В моем случае пространством имен является HelloApp, и оно проецируется на суффикс local

Затем в ресурсах создается объект привязки с ключом dateConverter.

И далее в самом выражении привязки мы подключем данный ресурс в качестве конвертера:

Converter={StaticResource dateConverter}

При этом здесь привязка идет к элементу выбора даты для двух объектов Label. Но только второй объект применяет конвертер:

Value Converter in Xamarin Forms

Возьмем другой случай. Допустим, нам надо привязать цвет метки к вводимому в текстовое поле значение. Для этого определим следующий конвертер:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace HelloApp
{
    public class StringToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Color color = Color.White;
            string colorStr = value.ToString().ToLower();
            switch(colorStr)
            {
                case "красный":
                    color = Color.Red;
                    break;
                case "желтый":
                    color = Color.Yellow;
                    break;
                case "зеленый":
                    color = Color.Green;
                    break;
                case "синий":
                    color = Color.Blue;
                    break;
            }
            return color;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Color.White;
        }
    }
}

Если вводится определенная строка, то конвертер возвращает определенный цвет. Теперь применим этот конвертер в XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
  <ContentPage.Resources> 
    <ResourceDictionary> 
      <local:StringToColorConverter x:Key="colorConverter" />
    </ResourceDictionary> 
  </ContentPage.Resources>
  <StackLayout>
    <Entry x:Name="entry1" Text="Red" />
    <Label x:Name="label1" Text="Xamarin" 
				TextColor="{Binding Source={x:Reference Name=entry1}, 
                                Converter={StaticResource colorConverter},  
                                Path=Text}" />
  </StackLayout>
</ContentPage>
Color Converter in Xamarin
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850