Преобразование значений привязки
Отрицание значений
Вам часто будет нужно отменить значение, к которому вы привязываетесь. Нередко это используется для отображения/скрытия элемента управления или его включения/отключения. Вы можете инвертировать значение привязки, добавив перед ним оператор «bang»: !.
Например, вы можете захотеть показать один элемент управления, когда другой элемент управления отключен.
<StackPanel> <TextBox Name="input" IsEnabled="{Binding AllowInput}"/> <TextBlock IsVisible="{Binding !AllowInput}">Sorry, no can do!</TextBlock> </StackPanel>
Отрицание также работает при привязке к не логическим значениям. Прежде всего, значение преобразуется в логическое значение с помощью Convert.ToBoolean
, а результат этого инвертируется. Поскольку целочисленное значение 0 считается ложным, а все остальные целочисленные значения считаются истинными, вы можете использовать это, чтобы показать сообщение, когда коллекция пуста:
<Panel> <ListBox Items="{Binding Items}"/> <TextBlock IsVisible="{Binding !Items.Count}">No results found</TextBlock> </Panel>
«double-bang» может использоваться для преобразования не логического значения в логическое значение. Например, чтобы скрыть элемент управления, когда коллекция пуста:
<Panel> <ListBox Items="{Binding Items}" IsVisible="{Binding !!Items.Count}"/> </Panel>
Преобразователи привязки
Для более сложных преобразований Avalonia поддерживает IValueConverter так же, как и другие платформы XAML.
Примечание. Интерфейс
IValueConverter
недоступен в стандарте .NET 2.0, поэтому мы поставляем собственный интерфейс в пространстве именAvalonia.Data.Converters
.
Использование идентично другим платформам XAML:
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ExampleApp;assembly=ExampleApp"> <Window.Resources> <local:MyConverter x:Key="myConverter"/> </Window.Resources> <TextBlock Text="{Binding Value, Converter={StaticResource myConverter}}"/> </Window>
Встроенные преобразователи
Avalonia поставляет ряд встроенных преобразователей значений для распространенных сценариев:
Конвертер | Описание |
---|---|
StringConverters.IsNullOrEmpty |
Возвращает true , если входная строка имеет значение null или пуста. |
StringConverters.IsNotNullOrEmpty |
Возвращает false , если входная строка имеет значение null или пуста. |
ObjectConverters.IsNull |
Возвращает true , если введено значение null |
ObjectConverters.IsNotNull |
Возвращает false , если введено значение null |
BoolConverters.And |
Преобразователь с несколькими значениями, который возвращает true , если все входные данные верны. |
BoolConverters.Or |
Преобразователь с несколькими значениями, который возвращает true , если какой-либо вход верен. |
Вы можете найти список конвертеров по умолчанию здесь: Пространство имен Avalonia.Data.Converters.
Примеры
Скрытие TextBlock
, если связанный текст является нулевым или пустым:
<TextBlock Text="{Binding MyText}" IsVisible="{Binding MyText, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
Скрытие ContentControl
, если связанное содержимое равно null или пусто:
<ContentControl Content="{Binding MyContent}" IsVisible="{Binding MyContent, Converter={x:Static ObjectConverters.IsNotNull}}"/>
Впредь предполагается, что конвертеры импортированы, как показано в предыдущем разделе «Привязка конвертеров».
Преобразование текста в конкретный регистр из параметра
<TextBlock Text="{Binding TheContent, Converter={StaticResource textCaseConverter}, ConverterParameter=lower}" />
public class TextCaseConverter : IValueConverter { public static readonly TextCaseConverter Instance = new(); public object? Convert( object? value, Type targetType, object? parameter, CultureInfo culture ) { if (value is string sourceText && parameter is string targetCase && targetType.IsAssignableTo(typeof(string))) { switch (targetCase) { case "upper": case "SQL": return sourceText.ToUpper(); case "lower": return sourceText.ToLower(); case "title": // Every First Letter Uppercase var txtinfo = new System.Globalization.CultureInfo("en-US",false).TextInfo; return txtinfo.ToTitleCase(sourceText); default: // invalid option, return the exception below break; } } // converter used for the wrong type return new BindingNotification(new InvalidCastException(), BindingErrorType.Error); } public object ConvertBack( object? value, Type targetType, object? parameter, CultureInfo culture ) { throw new NotSupportedException(); } }
Контекстное преобразование связанного объекта в разные целевые типы
<Image Width="42" Source="{Binding Animal, Converter={StaticResource animalConverter}}"/> <TextBlock Text="{Binding Animal, Converter={StaticResource animalConverter}}" />
public class AnimalConverter : IValueConverter { public static readonly AnimalConverter Instance = new(); public object? Convert( object? value, Type targetType, object? parameter, CultureInfo culture ) { if (value is Animal animal) { if (targetType.IsAssignableTo(typeof(IImage))) { img = @"icons/generic-animal-placeholder.png" switch (animal) { case Dog d: img = d.IsGoodBoy ? @"icons/dog-happy.png" : @"icons/dog.png"; break; case Cat: img = @"icons/cat.png"; break; // etc. etc. } // see https://docs.avaloniaui.net/docs/controls/image return BitmapAssetValueConverter.Instance .Convert(img, typeof(Bitmap), parameter, culture); } else if (targetType.IsAssignableTo(typeof(string))) { return !string.IsNullOrEmpty(animal.NickName) ? $"{animal.Name} \"{animal.NickName}\"" : animal.Name; } } // converter used for the wrong type return new BindingNotification(new InvalidCastException(), BindingErrorType.Error); } public object ConvertBack( object? value, Type targetType, object? parameter, CultureInfo culture ) { throw new NotSupportedException(); } }