L'article présente des approches généralisées à utiliser
lors de l'écriture de XAML
-code.
IValueConverter
Data Binding
XAML
WPF
UWP
Xamarin Forms
UI
SwitchConverter
KeyToValueConverter
InlineConverter
AggregateConverter
ResourceDictionary
avec le moteur de liaison de données sont des composants importants dans le développement d'interfaces utilisateur basées sur XAML
. Les convertisseurs de valeur impliquent la présence de logique dans une classe distincte qui implémente l'interface IValueConverter
. En règle générale, le nom de la classe reflète l'objectif fonctionnel et les instances sont déclarées dans le balisage.
Convertisseur de commutateur et convertisseur de clé en valeur
Dans la pratique, de nombreux convertisseurs ont des valeurs logiques triviales structure semblable à celle (?:)
ou des dessins if-else
, switch-case-default
. Cependant, il existe des modèles généralisés KeyToValueConverter
et SwitchConverter
qui vous permettent d'éviter d'ajouter des classes du même type dans la structure au projet en déclarant des valeurs booléennes et des branches directement dans le balisage.
Concept
<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>
Application
<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
), Case
s 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
Il est utile de placer les convertisseurs de valeurs génériques dans un dictionnaire de ressources distinct, puis de les fusionner en tant que ressources globales dans le fichier App.xaml. Cela vous permet de réutiliser des convertisseurs de valeur dans différentes représentations sans les re-déclarer.
<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>
Cadre Ace
Des exemples d'implémentation des convertisseurs présentés peuvent être trouvés dans la bibliothèque Ace Framework
gitlab bitbucket
Avec gratitude pour votre attention et votre intérêt!