Документация по Avalonia UI
< Все темы
Печать

Преобразование значений привязки

Отрицание значений

Вам часто будет нужно отменить значение, к которому вы привязываетесь. Нередко это используется для отображения/скрытия элемента управления или его включения/отключения. Вы можете инвертировать значение привязки, добавив перед ним оператор «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();
    }
}

Примеры

Примеры ValueConverter

Оглавление