[Программирование, .NET, Промышленное программирование, Xamarin] XAML Aesthetics: Value Converters
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
This article presents generalized approaches for using value converters into writing of XAML code.>> Read in Russian
IValueConverter Data Binding XAML WPF UWP Xamarin Forms UI SwitchConverter KeyToValueConverter InlineConverter AggregateConverter ResourceDictionary
Value converters together with a data binding mechanism are essential components into XAML-based development of user interfaces. Value converters imply the presence of logic placed in a separated class that implements the IValueConverter interface. Typically, the class name reflects the functional purpose, and the instances are declared in the markup.Switch Converter & Key To Value ConverterAt practice many value converters have trivial logic similar by structure with ternary operator (? :) or if-else, switch-case-default constructions. However, there are generalized patterns KeyToValueConverter and SwitchConverter, which allow to avoid adding to the project of similar by structure classes via declaring logical values and branches directly into markup.Conception
<KeyToValueConverter
Key="KeyForMatching"
Value="ValueIfKeyMatched"
ByDefault="ValueIfKeyNotMatched" />
<SwitchConverter
ByDefault="ValueZ">
<Case
Key="KeyA"
Value="ValueA" />
<Case
Key="KeyB"
Value="ValueB" />
<Case
Key="KeyC"
Value="ValueC" />
</SwitchConverter>
Usage
<KeyToValueConverter
x:Key="TrueToVisibleConverter"
Key="True"
Value="Visible"
ByDefault="Collapsed" />
<ProgressBar
Visibility="{Binding IsBusy, Converter={StaticResource TrueToVisibleConverter}}" />
<SwitchConverter
x:Key="CodeToBackgroundConverter"
ByDefault="White">
<Case
Key="R"
Value="Red" />
<Case
Key="G"
Value="Green" />
<Case
Key="B"
Value="Blue" />
</SwitchConverter>
<Control
Background="{Binding Code, Converter={StaticResource CodeToBackgroundConverter}}" />
KeyToValueConverter - checks the input value for compliance with the value from the Key property, if the match is met, then the value from the Value property is taken as the output, otherwise from the ByDefault property.SwitchConverter - searches for the first matching Case from the list by its key from the Key property, if the corresponding Case is found, then the value specified in it from the Value property is taken, otherwise from the ByDefault property, specified in the converter itself.If the property Value orByDefault is not explicitly set, but the corresponding condition is satisfied, then in this case, an ordinary forwarding of the input value as an output occurs.Also, it is sometimes useful for KeyToValueConverter to set a key in ConverterParameter via the KeySource property
<KeyToValueConverter
x:Key="EqualsToHiddenConverter"
KeySource="ConverterParameter"
Value="Collapsed"
ByDefault="Visible" />
<Control
Visiblity="{Binding Items.Count, ConverterParameter=0, Converter={StaticResource EqualsToHiddenConverter}}" />
<TextBlock
Visiblity="{Binding Text, ConverterParameter='Hide Me', Converter={StaticResource EqualsToHiddenConverter}}" />
There are four work modes of KeySource for special cases: Manual (by default) - the value from the Key property is always used as a key during matching, or the value is forwarded when it is not setConverterParameter - the value from the binding's property ConverterParameter is always used as the key during matching, or the value is passed through when it is not setPreferManual - if manual Key is explicitly set, it takes precedence over ConverterParameterPreferConverterParameter - if ConverterParameter is explicitly set, then it takes precedence over manual KeyNote that SwitchConverter, in addition to the usual Case, also has TypedCase, the main difference of which is matching by value type
<SwitchConverter
ByDefault="Undefined value">
<TypedCase
Key="system:String"
Value="String value" />
<Case
Key="0"
Value="Zero" />
<Case
Key="1"
Value="One" />
<TypedCase
Key="system:Int32"
Value="Int32 value" />
</SwitchConverter>
Sometimes it becomes necessary to debug the value converter. For this purpose, SwitchConverter has a DiagnosticKey property, if it is been set, then when the data binding is been triggered, diagnostic messages of the following format will be displayed in 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);
<SwitchConverter
DiagnosticKey="UniqDiagnosticKey"
x:Key="CodeToBackgroundConverter"
ByDefault="White">
...
</SwitchConverter>
Dependency Value ConverterIt is also useful to declare Key, Value and ByDefault properties as Dependency Properties, that means inheritance of converters and Cases from the DependencyObject class. Although value converters are usually not elements of the visual tree, which partly limits the work of the data binding mechanism, nevertheless, it remains possible to bind to static resources or descendants of the Binding class, for example
<KeyToValueConverter
Key="AnyKey"
Value="{Binding MatchedValue, Source={StaticResource AnyResource}}"
ByDefault="{Binding DefaultValue, Source={StaticResource AnyResource}}" />
<KeyToValueConverter
Key="AnyKey"
Value="{Localizing MatchedTitle}"
ByDefault="{Localizing DefaultTitle}" />
Inline ConverterInline Converter allow to transfer the values conversion logic from a separate class that implements the IValueConverter interface into the code-behind class of a concrete view based on the event model.This allows to access the view and its individual visual elements from the conversion logic during implementation of complex scenarios that are difficult to implement with the classical approach.To do this, you need to add the converter declaration to the markup, and into the code-behind class define handlers for the corresponding Converting and ConvertingBack events
<Grid>
<Grid.Resources>
<InlineConverter
x: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 view
e.ConvertedValue = // set output value
$"DataContext: {DataContext}, Converter Value: {e.Value}";
}
private void InlineConverter_OnConvertingBack(object sender, ConverterEventArgs e)
{
// ...
}
Aggregate ConverterAggregate converter intends for combining converters into chains, while the value is converted sequentially in the order in which nested converters are declared.
<AggregateConverter>
<StepAConverter />
<StepBConverter />
<StepCConverter />
</AggregateConverter>
App.xamlIt is useful to locate generic value converters in a separate Resource Dictionary and then merge them as global resources into the App.xaml file. This allows to reuse value converters in different views without re-declaring them.
<Application
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://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 FrameworkExamples of implementation of the presented converters can be found into the Ace Framework library gitlab bitbucketWith gratitude for your attention and interest!
===========
Источник:
habr.com
===========
Похожие новости:
- [Прототипирование, Разработка под Arduino, Производство и разработка электроники, DIY или Сделай сам] Отладочная плата для Arduino Nano 2 часть
- [Open source, Системное программирование, Программирование микроконтроллеров, Процессоры] О кэшах в микроконтроллерах ARM
- [Программирование, .NET, Промышленное программирование, Xamarin] Эстетика XAML: конвертеры значений
- [Разработка веб-сайтов, Программирование, IT-инфраструктура, Управление проектами, DevOps] Веб-разработка с нуля: руководство для молодых команд по созданию инфраструктуры CI/CD и процесса разработки
- [Разработка веб-сайтов, JavaScript, Программирование] Заметка о перебираемых объектах
- [Семантика, Программирование, Prolog, Бизнес-модели] Проектируем мульти-парадигменный язык программирования. Часть 3 — Обзор языков представления знаний
- [Промышленное программирование, Разработка робототехники, Программирование микроконтроллеров, Разработка для интернета вещей, Производство и разработка электроники] ModBus Slave RTU/ASCII без смс и регистрации
- [Python, Программирование, Git, GitHub, Учебный процесс в IT] 25 лучших репозиториев GitHub для разработчиков Python (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование] Управление памятью в JavaScript (перевод)
- [Программирование, Kotlin, Управление продуктом] Kotlin: язык программирования как продукт
Теги для поиска: #_programmirovanie (Программирование), #_.net, #_promyshlennoe_programmirovanie (Промышленное программирование), #_xamarin, #_ivalueconverter, #_data_binding, #_xaml, #_wpf, #_uwp, #_xamarin_forms, #_ui, #_switchconverter, #_keytovalueconverter, #_programmirovanie (
Программирование
), #_.net, #_promyshlennoe_programmirovanie (
Промышленное программирование
), #_xamarin
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 26-Ноя 10:04
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
This article presents generalized approaches for using value converters into writing of XAML code.>> Read in Russian IValueConverter Data Binding XAML WPF UWP Xamarin Forms UI SwitchConverter KeyToValueConverter InlineConverter AggregateConverter ResourceDictionary
<KeyToValueConverter
Key="KeyForMatching" Value="ValueIfKeyMatched" ByDefault="ValueIfKeyNotMatched" /> <SwitchConverter ByDefault="ValueZ"> <Case Key="KeyA" Value="ValueA" /> <Case Key="KeyB" Value="ValueB" /> <Case Key="KeyC" Value="ValueC" /> </SwitchConverter> <KeyToValueConverter
x:Key="TrueToVisibleConverter" Key="True" Value="Visible" ByDefault="Collapsed" /> <ProgressBar Visibility="{Binding IsBusy, Converter={StaticResource TrueToVisibleConverter}}" /> <SwitchConverter
x:Key="CodeToBackgroundConverter" ByDefault="White"> <Case Key="R" Value="Red" /> <Case Key="G" Value="Green" /> <Case Key="B" Value="Blue" /> </SwitchConverter> <Control Background="{Binding Code, Converter={StaticResource CodeToBackgroundConverter}}" /> <KeyToValueConverter
x:Key="EqualsToHiddenConverter" KeySource="ConverterParameter" Value="Collapsed" ByDefault="Visible" /> <Control Visiblity="{Binding Items.Count, ConverterParameter=0, Converter={StaticResource EqualsToHiddenConverter}}" /> <TextBlock Visiblity="{Binding Text, ConverterParameter='Hide Me', Converter={StaticResource EqualsToHiddenConverter}}" /> <SwitchConverter
ByDefault="Undefined value"> <TypedCase Key="system:String" Value="String value" /> <Case Key="0" Value="Zero" /> <Case Key="1" Value="One" /> <TypedCase Key="system:Int32" Value="Int32 value" /> </SwitchConverter> 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); <SwitchConverter
DiagnosticKey="UniqDiagnosticKey" x:Key="CodeToBackgroundConverter" ByDefault="White"> ... </SwitchConverter> <KeyToValueConverter
Key="AnyKey" Value="{Binding MatchedValue, Source={StaticResource AnyResource}}" ByDefault="{Binding DefaultValue, Source={StaticResource AnyResource}}" /> <KeyToValueConverter Key="AnyKey" Value="{Localizing MatchedTitle}" ByDefault="{Localizing DefaultTitle}" /> <Grid>
<Grid.Resources> <InlineConverter x: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 view e.ConvertedValue = // set output value $"DataContext: {DataContext}, Converter Value: {e.Value}"; } private void InlineConverter_OnConvertingBack(object sender, ConverterEventArgs e) { // ... } <AggregateConverter>
<StepAConverter /> <StepBConverter /> <StepCConverter /> </AggregateConverter> <Application
xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://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> =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_.net, #_promyshlennoe_programmirovanie ( Промышленное программирование ), #_xamarin |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 26-Ноя 10:04
Часовой пояс: UTC + 5