Конвертеры¶
Конвертеры предназначены для использования в привязках WPF (XAML) для преобразования значений перед отображением или управлением визуальными свойствами. Все конвертеры реализуют IValueConverter либо IMultiValueConverter и могут быть объявлены как ресурсы.
Хотя конвертеры и относятся к UX/UI, располагаются они в библиотеке ModPlusAPI!
В примерах ниже предполагается, что:
<Window ...
xmlns:conv="clr-namespace:ModPlusAPI.Converters;assembly=ModPlusAPI">
<Window.Resources>
<conv:BooleanToOpacityConverter x:Key="BoolToOpacity"
TrueOpacity="1.0"
FalseOpacity="0.3" />
<conv:BooleanToVisibilityConverter x:Key="BoolToVisibility"
TrueVisibility="Visible"
FalseVisibility="Collapsed" />
<conv:BooleanInverseConverter x:Key="BoolInverse" />
<conv:EnumToIntConverter x:Key="EnumToInt" />
<conv:EnumDisplayNameConverter x:Key="EnumDisplayName" />
<conv:MultiBooleanConverter x:Key="MultiBool" />
</Window.Resources>
...
</Window>
1) BooleanToOpacityConverter¶
Назначение¶
Преобразует bool в прозрачность (double для свойства Opacity). Удобно, когда нужно не «рубить» видимость (Visibility), а мягко приглушать элемент.
Свойства¶
TrueOpacity: double— значение дляtrue(по умолчанию1.0)FalseOpacity: double— значение дляfalse(по умолчанию0.3)
Поведение¶
Convert:true → TrueOpacity,false → FalseOpacity. Если вход неbool, возвращает исходное значение без изменений.ConvertBack: если вход —double, сравнивает его сTrueOpacity/FalseOpacityс допуском0.01и возвращаетbool. Иначе — возвращает вход.
Практика: держите
FalseOpacityв диапазоне0.2–0.5— элемент остаётся видимым, но «приглушён».
Примеры¶
<!-- При IsValid = true полностью видим, иначе приглушён -->
<TextBlock Text="Данные валидны"
Opacity="{Binding IsValid, Converter={StaticResource BoolToOpacity}}" />
2) BooleanToVisibilityConverter¶
Назначение¶
Преобразует bool в Visibility. Основной способ «показывать/скрывать» элементы.
Свойства¶
TrueVisibility: Visibility— значение дляtrue(по умолчаниюVisible)FalseVisibility: Visibility— значение дляfalse(по умолчаниюCollapsed)
Если нужна «пустая зона» вместо исчезновения, используйте
FalseVisibility="Hidden".
Поведение¶
Convert:true → TrueVisibility,false → FalseVisibility. Не-boolвозвращается как есть.ConvertBack:Visibility→bool(сравнение сTrueVisibility/FalseVisibility). Иначе — возвращает вход.
Примеры¶
<!-- Кнопка отображается только когда можно сохранить -->
<Button Content="Сохранить"
Visibility="{Binding CanSave, Converter={StaticResource BoolToVisibility}}" />
3) BooleanInverseConverter¶
Назначение¶
Инвертирует булево значение. Полезно, когда логика «обратная» и плодить лишние свойства во ViewModel не хочется.
Поведение¶
Convert/ConvertBack:true ↔ false. Если вход неbool, возвращается вход.
Примеры¶
<!-- Заблокировать кнопку, пока IsBusy = true -->
<Button Content="Выполнить"
IsEnabled="{Binding IsBusy, Converter={StaticResource BoolInverse}}" />
4) MultiBooleanConverter (мульти-привязка)¶
Назначение¶
Агрегирует несколько bool и возвращает true, только если все они true. Любое false — результат false.
Поведение¶
Convert(object[] values, ...): проходит по массиву и если встречаетbool false— возвращаетfalse.nullи значения, не являющиесяbool, игнорируются (то есть не делают результатfalse).- Обратного преобразования нет (исключение
NotImplementedException).
Примеры¶
<!-- Кнопка включена, только если два условия одновременно истинны -->
<Button Content="Далее">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource MultiBool}">
<Binding Path="IsFormValid"/>
<Binding Path="IsNotBusy"/>
</MultiBinding>
</Button.IsEnabled>
</Button>
Лайфхак: если какие-то из условий могут быть
null, это не сломает конвертер — они просто не повлияют на итог.
5) EnumToIntConverter (двусторонний)¶
Назначение¶
Двустороннее преобразование Enum ↔ int. Полезно для:
- биндинга к
SelectedIndexили числовым настройкам - сериализации числовых значений в настройках
Требование¶
В ConverterParameter нужно передать тип перечисления (System.Type).
Поведение¶
Convert:Enum→intчерезEnum.Parseпо имени (используетсяparameterкак тип).ConvertBack:int→Enum(Enum.Parseпо числу). Если параметр не передан/тип не совпадает — возвращает вход.
В XAML тип удобно передать как
ConverterParameter={x:Type local:MyEnum}.
Примеры¶
<!-- Привязываем ComboBox.SelectedIndex к значению enum -->
<ComboBox ItemsSource="{Binding Source={x:Static local:MyEnum.GetValues}}"
SelectedIndex="{Binding SelectedMode,
Converter={StaticResource EnumToInt},
ConverterParameter={x:Type local:MyEnum},
Mode=TwoWay}" />
// ViewModel
public MyEnum SelectedMode { get; set; }
public enum MyEnum { None = 0, Fast = 1, Safe = 2 }
Частая ошибка: забыть
ConverterParameter. Тогда парсинг не знает, к какому типу enum приводить.
6) EnumDisplayNameConverter¶
Назначение¶
Показывает для элементов Enum локализованные/человекочитаемые названия, заданные атрибутом System.ComponentModel.DataAnnotations.DisplayAttribute (свойство Name). Также умеет искать элемент по строке при обратном преобразовании.
Подготовка перечисления¶
using System.ComponentModel.DataAnnotations;
public enum OperationMode
{
[Display(Name = "Быстрый режим")]
Fast = 0,
[Display(Name = "Безопасный режим")]
Safe = 1,
[Display(Name = "Экономичный режим")]
Eco = 2
}
Поведение¶
Convert: берёт поле enum по имени и читаетDisplayAttribute.Name. Еслиvalue == null— бросаетArgumentException.ConvertBack: по входной строке перебирает все значения enum и возвращает то, у которогоDisplayAttribute.Nameсовпадает со строкой. ЕслиvalueнеstringилиparameterнеType— бросаетArgumentException.
Рекомендация: используйте
Mode=TwoWayтолько если действительно ожидаете ввод строки пользователем (например, черезComboBox/AutoComplete). Для одностороннего отображения оставьтеMode=OneWay.
Примеры¶
<!-- Отобразить подпись текущего режима -->
<TextBlock Text="{Binding SelectedMode,
Converter={StaticResource EnumDisplayName},
Mode=OneWay}" />
<!-- Выпадающий список с локализованными подписями -->
<ComboBox SelectedItem="{Binding SelectedMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDisplayName},
ConverterParameter={x:Type local:OperationMode}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsSource>
<x:Array Type="{x:Type local:OperationMode}">
<local:OperationMode>Fast</local:OperationMode>
<local:OperationMode>Safe</local:OperationMode>
<local:OperationMode>Eco</local:OperationMode>
</x:Array>
</ComboBox.ItemsSource>
</ComboBox>
Частая ошибка: не передать тип в
ConverterParameterдляConvertBack. В таком случае сопоставление по строке выполнить нельзя.