O artigo apresenta abordagens generalizadas para usar ao escrever XAML-code.

IValueConverterData BindingXAMLWPFUWPXamarin FormsUISwitchConverterKeyToValueConverterInlineConverterAggregateConverterResourceDictionary
junto com o mecanismo de vinculação de dados são componentes importantes no desenvolvimento de interfaces de usuário baseadas em XAML. Os conversores de valor implicam na presença de lógica em uma classe separada que implementa a interface IValueConverter. Normalmente, o nome da classe reflete a finalidade funcional e as instâncias são declaradas na marcação.
Conversor de mudança e chave para conversor de valor
Na prática, muitos conversores têm valores lógicos triviais de uma estrutura semelhante a (?:) ou projetos if-else, switch-case-default. No entanto, existem modelos generalizados KeyToValueConverter e SwitchConverterque permitem evitar a adição de classes do mesmo tipo na estrutura do projeto, declarando valores booleanos e ramificações diretamente na marcação.
Conceito
<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>Inscrição
<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 - Key, , Value, ByDefault.
SwitchConverter - Case Key, Case , ¨C31C, ¨C90C¨C32C, .
Value ByDefault , , .
KeyToValueConverter ConverterParameter KeySource
<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}}" /> KeySource :
Manual (by default) - Key ,
ConverterParameter - ConverterParameter ,
PreferManual - manual Key , ConverterParameter
PreferConverterParameter - ConverterParameter , manual Key
, SwitchConverter Case TypedCase,
<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> . 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);<SwitchConverter
DiagnosticKey="UniqDiagnosticKey"
x:Key="CodeToBackgroundConverter"
ByDefault="White">
...
</SwitchConverter>Dependency Value Converter
Key, Value ByDefault (Dependency Properties), Cases DependencyObject. , , Binding,
<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 Converter
, IValueConverter, code-behind .
, .
, code-behind Converting ConvertingBack
<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 Converter
, .
<AggregateConverter>
<StepAConverter />
<StepBConverter />
<StepCConverter />
</AggregateConverter>App.xaml
É útil colocar conversores de valor genérico em um Dicionário de Recursos separado e, em seguida, mesclá-los como recursos globais no arquivo App.xaml. Isso permite que você reutilize os conversores de valor em diferentes representações, sem declará-los novamente.
<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 Framework
Exemplos de implementação dos conversores apresentados podem ser encontrados na biblioteca Ace Framework gitlab bitbucket
Muito obrigado pela atenção e interesse!