С помощью свойств конвертеров мы можем передать в ковертеры извне некоторые значения, которые затем можно использовать в процессе привязки. Например, определим следующий конвертер, который конвертирует имя пользователя в условный статус:
using System.Globalization; namespace HelloApp { public class StringToStatusConverter : IValueConverter { public string ApprovedStatus { get; set; } = "Approved"; public string DeniedStatus { get; set; } = "Denied"; public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string username = (string)value; if (username == "admin") return ApprovedStatus; return DeniedStatus; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var status = value.ToString(); if (status == ApprovedStatus) return "admin"; return "user"; } } }
Конвертер содержит два свойства. Если свойство источника-привязки содержит значение "admin", то возвращаем значение свойства Approved, иначе возвращаем значение свойства Denied.
Применим этот конвертер на странице
namespace HelloApp { class StartPage : ContentPage { public StartPage() { Label label = new Label(); Entry entry= new Entry(); Binding binding = new Binding { Source = entry, Path = "Text", Converter = new StringToStatusConverter() { ApprovedStatus = "Доступ одобрен", DeniedStatus = "Доступ отклонен" } }; label.SetBinding(Label.TextProperty, binding); StackLayout stackLayout = new StackLayout() { Children = { entry, label}, Padding = 20 }; Content = stackLayout; } } }
здесь элемент Label привязан к текстовому полю и использует конвертер привязки StringToStatusConverter, у которого свойства Approved и Denied хранят определенные сообщения. В итоге при вводе в текстовое поле мы увидим одно из этих сообщений
Аналогичный пример в XAML:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloApp" x:Class="HelloApp.MainPage"> <StackLayout Padding="20"> <Entry x:Name="entry" /> <Label> <Label.Text> <Binding Source="{x:Reference entry}" Path="Text"> <Binding.Converter> <local:StringToStatusConverter ApprovedStatus="Доступ разрешен" DeniedStatus="Доступ запрещен" /> </Binding.Converter> </Binding> </Label.Text> </Label> </StackLayout> </ContentPage>
Но мы можем пойти дальше и использовать свойства не просто как хранилище некоторых значений, но и как хранилища некоторого состояния элемента.
Например, настроим с помощью свойств конвертера стилизацию. Для этого определим следующий конвертер StringToStyleConverter
:
using System.Globalization; namespace HelloApp { public class StringToStyleConverter : IValueConverter { public Style ApprovedStatus { get; set; } public Style DeniedStatus { get; set; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string username = (string)value; if (username == "admin") return ApprovedStatus; return DeniedStatus; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var status = value as Style; if (status == ApprovedStatus) return "admin"; return "user"; } } }
Этот конвертер аналогичен предыдущему, только теперь его свойства представлять стиль - объект Style.
Применим этот конвертер в коде xaml на странице:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloApp" x:Class="HelloApp.MainPage"> <StackLayout Padding="20"> <Entry x:Name="entry" /> <Label> <Label.Style> <Binding Source="{x:Reference entry}" Path="Text"> <Binding.Converter> <local:StringToStyleConverter> <local:StringToStyleConverter.ApprovedStatus> <Style TargetType="Label"> <Setter Property="Text" Value="Доступ разрешен" /> <Setter Property="TextColor" Value="Green" /> </Style> </local:StringToStyleConverter.ApprovedStatus> <local:StringToStyleConverter.DeniedStatus> <Style TargetType="Label"> <Setter Property="Text" Value="Доступ запрещен" /> <Setter Property="TextDecorations" Value="Underline" /> <Setter Property="TextColor" Value="Red" /> </Style> </local:StringToStyleConverter.DeniedStatus> </local:StringToStyleConverter> </Binding.Converter> </Binding> </Label.Style> </Label> </StackLayout> </ContentPage>
Здесь свойство Style элемента Label привязано к свойству Text элемента Entry. Благодаря конвертеру мы можем транслировать введенный текст в конкретный стиль. С помощью свойств конвертера в коде xaml задаем два стиля, в частности, текст, его цвет и атрибуты шрифта. В результате в зависимости от введенного текста мы увидим различную стилизацию метки:
Класс Binding имеет свойство ConverterParameter, через которое можно передать данные в конвертер через третий параметр методов Convert()
и ConvertBack()
.
К примеру, определим следующий конвертер:
using System.Globalization; namespace HelloApp { public class StringToCurrencyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if(parameter.ToString()== "euro") { return $"{value} €"; } return $"{value} $"; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value.ToString().Replace(" €", "").Replace(" $", ""); } } }
В обоих методах через параметр parameter
можно получить переданное извне значение, которое может представлять любой тип. Для примера, выполняем форматирование валют - если передается строка "euro",
то добавляем в конец значения символ евро, иначе добавляем символ доллара.
Используем конвертер в коде C# страницы:
namespace HelloApp { class StartPage : ContentPage { public StartPage() { Entry entry= new Entry(); Label euroLabel = new Label(); Label dollarLabel = new Label(); Binding euroBinding = new Binding { Source = entry, Path = "Text", Converter = new StringToCurrencyConverter(), ConverterParameter = "euro" }; Binding dollarBinding = new Binding { Source = entry, Path = "Text", Converter = new StringToCurrencyConverter(), ConverterParameter = "dollar" }; euroLabel.SetBinding(Label.TextProperty, euroBinding); dollarLabel.SetBinding(Label.TextProperty, dollarBinding); StackLayout stackLayout = new StackLayout() { Children = { entry, euroLabel, dollarLabel}, Padding = 20 }; Content = stackLayout; } } }
В данном случае для наглядности определяем две метки с разными привязками. Обе привязки используют один и тот же конвертер, однако передают ему разные значения для параметра
Аналогичный пример в xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloApp" x:Class="HelloApp.MainPage"> <StackLayout Padding="20"> <Entry x:Name="entry" /> <Label> <Label.Text> <Binding Source="{x:Reference entry}" Path="Text" ConverterParameter="euro"> <Binding.Converter > <local:StringToCurrencyConverter /> </Binding.Converter> </Binding> </Label.Text> </Label> <Label> <Label.Text> <Binding Source="{x:Reference entry}" Path="Text" ConverterParameter="dollar"> <Binding.Converter > <local:StringToCurrencyConverter /> </Binding.Converter> </Binding> </Label.Text> </Label> </StackLayout> </ContentPage>