Русский
Русский
English
Статистика
Реклама

Эстетика XAML конвертеры значений

В статье представлены обобщённые подходы применения конвертеров значений при написании XAML-кода.

IValueConverterData BindingXAMLWPFUWPXamarin FormsUISwitchConverterKeyToValueConverterInlineConverterAggregateConverterResourceDictionary

Конвертеры значенийсовместно с механизмом привязки данных являются важными компонентами в разработке пользовательских интерфейсов на основеXAML. Конвертеры значений подразумевают наличие логики, помещенной в отдельный класс, реализующий интерфейсIValueConverter. Обычно имя класса отражает функциональное назначение, а сами экземпляры декларируются в разметке.

Switch Converter & Key To Value Converter

На практике многие конвертеры значений имеют тривиальную логику схожую по структуре стернарным оператором (?:)или конструкциямif-else,switch-case-default. Однако существуют обобщенные шаблоныKeyToValueConverterиSwitchConverter, которые позволяют избежать добавления в проект однотипных по структуре классов путём декларирования логических значений и ветвлений непосредственно в разметке.

Концепция

<KeyToValueConverterKey="KeyForMatching"Value="ValueIfKeyMatched"ByDefault="ValueIfKeyNotMatched" /><SwitchConverterByDefault="ValueZ"><CaseKey="KeyA"Value="ValueA" /><CaseKey="KeyB"Value="ValueB" /><CaseKey="KeyC"Value="ValueC" /></SwitchConverter>

Применение

<KeyToValueConverterx:Key="TrueToVisibleConverter"Key="True"Value="Visible"ByDefault="Collapsed" /><ProgressBarVisibility="{Binding IsBusy, Converter={StaticResource TrueToVisibleConverter}}" />
<SwitchConverterx:Key="CodeToBackgroundConverter"ByDefault="White"><CaseKey="R"Value="Red" /><CaseKey="G"Value="Green" /><CaseKey="B"Value="Blue" /></SwitchConverter><ControlBackground="{Binding Code, Converter={StaticResource CodeToBackgroundConverter}}" />

KeyToValueConverter- проверяет входное значение на соответствие со значением из свойстваKey, если соответствие выполнено, то в качестве выходного берётся значение из свойстваValue, в противном случае из свойстваByDefault.

SwitchConverter- выполняет поиск первого соответствующегоCaseиз списка по его ключу из свойстваKey, если соответствующийCaseнайден, то берётся заданное в нём значение из свойстваC31C, в противном случае из свойстваC90CC32C, заданного в самом конвертере значений.

Если свойствоValueилиByDefaultявно не задано, но выполняется соответствующее ему условие, то в таком случае происходит обыкновенный проброс входного значения в качестве выходного.

Также уKeyToValueConverterиногда полезно задавать ключ вConverterParameterчерез свойствоKeySource

<KeyToValueConverterx:Key="EqualsToHiddenConverter"KeySource="ConverterParameter"Value="Collapsed"ByDefault="Visible" /><ControlVisiblity="{Binding Items.Count, ConverterParameter=0, Converter={StaticResource EqualsToHiddenConverter}}" /><TextBlockVisiblity="{Binding Text, ConverterParameter='Hide Me', Converter={StaticResource EqualsToHiddenConverter}}" />

Для особых случаев уKeySourceвозможны четыре режима работы:

Manual(by default) - в качестве ключа при проверке соответствия всегда используется значение из свойстваKeyлибо выполняется проброс значения, когда оно не задано

ConverterParameter- в качестве ключа всегда используется значение из свойства привязкиConverterParameterлибо выполняется проброс значения, когда оно не задано

PreferManual- еслиmanual Keyявно задан, то он имеет приоритет передConverterParameter

PreferConverterParameter- еслиConverterParameterявно задан, то он имеет приоритет перед manualKey

Стоит также отметить, что уSwitchConverterпомимо обычныхCaseдоступны такжеTypedCase, основное отличие которых в проверке на соответствие по типу значения

<SwitchConverterByDefault="Undefined value"><TypedCaseKey="system:String"Value="String value" /><CaseKey="0"Value="Zero" /><CaseKey="1"Value="One" /><TypedCaseKey="system:Int32"Value="Int32 value" /></SwitchConverter>

Иногда возникает необходимость продебажить работу конвертера значений. Для этой цели уSwitchConverterпредусмотрено свойствоDiagnosticKey, если оно задано, то при срабатывании привязки данных вTraceбудут выводится диагностические сообщения следующего формата

var diagnosticMessage = matchedCase.Is()? $"{DiagnosticKey}: '{matchedValue}' matched by key '{matchedCase.Key}' for '{value}' and converted to '{convertedValue}'": $"{DiagnosticKey}: The default value '{matchedValue}' matched for '{value}' and converted to '{convertedValue}'";Trace.WriteLine(diagnosticMessage);
<SwitchConverterDiagnosticKey="UniqDiagnosticKey"x:Key="CodeToBackgroundConverter"ByDefault="White">...</SwitchConverter>

Dependency Value Converter

Также свойства Key, Value и ByDefault полезно объявлять в качестве свойств зависимости (Dependency Properties), то есть наследовать конвертеры и Cases от класса DependencyObject. Хотя конвертеры значений обычно не являются элементами визуального дерева, что отчасти ограничивает работу механизма привязки данных, тем не менее остаётся возможность производить привязку к статическим ресурсам или наследникам класса Binding, например

<KeyToValueConverterKey="AnyKey"Value="{Binding MatchedValue, Source={StaticResource AnyResource}}"ByDefault="{Binding DefaultValue, Source={StaticResource AnyResource}}" /><KeyToValueConverterKey="AnyKey"Value="{Localizing MatchedTitle}"ByDefault="{Localizing DefaultTitle}" />

Inline Converter

Встраиваемый конвертер позволят перенести логику по преобразованию значений из отдельного класса, реализующего интерфейс IValueConverter, в code-behind класс конкретного представления на основе событийной модели.

Это позволяет получить доступ к представлению и его отдельным визуальным элементам из логики конвертирования при реализации сложных сценариев, которые затруднительно реализовать при классическом подходе.

Для этого необходимо добавить декларацию конвертера в разметку, а code-behind классе определить обработчики для соответствующих событий Converting и ConvertingBack

<Grid><Grid.Resources><InlineConverterx:Key="ComplexInlineConverter"Converting="InlineConverter_OnConverting"ConvertingBack="InlineConverter_OnConverting" /></Grid.Resources><TextBlock Text="{Binding Number, Converter={StaticResource InlineConverter}}"/></Grid>
private void InlineConverter_OnConverting(object sender, ConverterEventArgs e){// e.Value - access to input value// this.DataContext - access to Data Context or another properties of the view// access to child visual elements of this root viewe.ConvertedValue = // set output value$"DataContext: {DataContext}, Converter Value: {e.Value}";}private void InlineConverter_OnConvertingBack(object sender, ConverterEventArgs e){// ...}

Aggregate Converter

Агрегирующий конвертер предназначен для объединения конвертеров в цепочки, при этом преобразование значения происходит последовательно в порядке декларирования вложенных конвертеров.

<AggregateConverter><StepAConverter /><StepBConverter /><StepCConverter /></AggregateConverter>

App.xaml

Обобщённые конвертеры значений полезно помещать в отдельный Resource Dictionary, а затем мержить их в качестве глобальных ресурсов в файл App.xaml. Это позволяет переиспользовать конвертеры значений в различных представлениях без их повторного декларирования.

<Applicationxmlns="http://personeltest.ru/away/xamarin.com/schemas/2014/forms"xmlns:x="http://personeltest.ru/away/schemas.microsoft.com/winfx/2009/xaml"x:Class="Any.App"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="AppConverters.xaml" />...</ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources></Application>

Ace Framework

Примеры реализации представленных конвертеров можно найти в библиотеке Ace Framework gitlab bitbucket

С благодарностью за внимание и интерес!

Источник: habr.com
К списку статей
Опубликовано: 04.11.2020 16:22:09
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Программирование

Net

Промышленное программирование

Xamarin

Ivalueconverter

Data binding

Xaml

Wpf

Uwp

Xamarin forms

Ui

Switchconverter

Keytovalueconverter

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru