Liaison de données avec des types qui ne correspondent pas
- 10 minutes
Parfois, les données que vous utilisez ne correspondent pas au type de données de la propriété de contrôle affichant les données. Par exemple, vous pouvez avoir une valeur monétaire stockée dans un type decimal que vous souhaitez afficher sur un contrôle Label, mis en forme en tant que devise. Un exemple plus compliqué serait avec l’application météorologique présentée dans le module. Une image est censée être affichée en fonction de la valeur d’énumération Sunny ou Cloudy de la prévision météorologique, mais vous ne pouvez pas lier la valeur d’énumération de la source à la propriété d’image d’une cible. Cette unité examine les façons dont vous pouvez convertir des données.
Mise en forme de chaîne
Un type intrinsèque que vous voulez afficher en tant que chaîne mise en forme constitue une incompatibilité de type courante. Comme lorsque vous souhaitez afficher des parties d’une valeur DateTime ou mettre en forme un type decimal en tant que devise.
Supposons que vous souhaitez afficher le montant dû sur une facture et que vous disposez de cette propriété sur votre objet de données :
public decimal BillAmount { get; set; }
Le montant dû est de 22,0304. Vous pouvez utiliser deux contrôles d’étiquette pour afficher du texte et le montant en dollar, comme illustré dans l’extrait de code suivant :
<HorizontalStackLayout>
<Label Text="You owe" Margin="0,0,5,0" />
<Label Text="{Binding BillAmount}" />
<Label Text="to the bank" Margin="5,0,0,0" />
</HorizontalStackLayout>
Cela génère une chaîne à l’interface utilisateur qui ressemble à You owe 22.0304 to the bank, mais il manque le symbole monétaire et il peut y avoir trop de décimales, ou trop peu, en fonction de la devise locale. Normalement, vous traitez la valeur en tant que chaîne avec le spécificateur de format « C » (ou devise) dans le code, comme suit :
string formattedBillAmount = string.Format("{0:C}", BillAmount);
Mais pour utiliser la mise en forme dans la liaison de données, vous devez soit configurer l'objet de données pour qu'il vous fournisse cette chaîne formatée en tant que propriété distincte, soit l'intercepter d'une manière ou d'une autre et la formater vous-même. Heureusement, les liaisons .NET MAUI permettent de mettre en forme des chaînes avec la propriété de liaison StringFormat. La chaîne de format suit les mêmes règles que la méthode String.Format. Placez la chaîne de format entre guillemets simples afin que l’analyseur XAML ne soit pas dérouté par les accolades. Le paramètre de format de chaîne 0 est la valeur de propriété que traitent les processus de liaison.
<Label Text="{Binding BillAmount, StringFormat='You owe {0:C} to the bank'}" />
Considérez le XAML suivant, qui illustre l’affichage de BillAmount des deux façons :
<VerticalStackLayout Padding="10">
<HorizontalStackLayout>
<Label Text="You owe" Margin="0,0,5,0" />
<Label Text="{Binding BillAmount}" />
<Label Text="to the bank" Margin="5,0,0,0" />
</HorizontalStackLayout>
<HorizontalStackLayout>
<Label Text="{Binding BillAmount, StringFormat='You owe {0:C} to the bank'}" />
</HorizontalStackLayout>
</VerticalStackLayout>
L’image suivante illustre ce que produit la sortie XAML à l’écran :
Le XAML utilisant la propriété de liaison StringFormat est plus simple que l’autre XAML et vous avez accès au système de mise en forme de chaîne puissant de .NET.
Conversion de type personnalisée
La propriété de liaison StringFormat est pratique lors de l’affichage d’une valeur sous forme de chaîne, mais pas lorsque vous souhaitez convertir quelque chose comme une Color ou une Image à partir d’un autre type. Dans ces cas, vous devez écrire du code de conversion personnalisé.
Supposons que vous invitez l’utilisateur à choisir un mot de passe et que vous souhaitez utiliser une couleur dans l’interface utilisateur pour indiquer la force du mot de passe. Il existe trois niveaux de force : faible, bon, fort. La force est basée sur le nombre de caractères dans le mot de passe. Pour donner des commentaires immédiats à l’utilisateur sur sa force de mot de passe, vous souhaitez que l’arrière-plan du contrôle Entry contenant le mot de passe change en fonction de la force. L’image suivante illustre ces trois niveaux de force : faible, bon et fort.
Parmi les trois contrôles d’entrée de la capture d’écran, le premier comporte quatre caractères entrés et comporte un arrière-plan rouge. La deuxième comporte neuf caractères entrés et comporte un arrière-plan jaune. Le dernier contrôle d’entrée comporte 15 caractères et comporte un arrière-plan bleu.
Ces niveaux sont affectés à l’énumération Strength :
private enum Strength
{
Weak,
Good,
Strong
}
Un objet de données est affecté en tant que BindingContext de la page, qui contient la force du mot de passe avec la propriété PasswordStrength. À mesure que l’utilisateur tape un mot de passe, la propriété PasswordStrength est modifiée en fonction de la longueur du mot de passe. Étant donné que l’objet de données contient la propriété PasswordStrength, vous liez cette propriété à la BackgroundColor du contrôle Entry :
<Entry BackgroundColor="{Binding PasswordStrength} ... />
Il y a un problème ici, cependant. La PasswordStrength est de type Strength alors que BackgroundColor est une Color. Ces types ne sont pas compatibles entre eux. .NET MAUI permet de résoudre ces problèmes d’incompatibilité de type, la propriété Converter de la liaison.
Un convertisseur de liaison fait précisément ce que son nom indique. Il convertit entre la source et la cible de liaison. Les convertisseurs sont implémentés via l’interface IValueConverter.
Implémenter IValueConverter
Vous créez votre logique de conversion dans une classe qui implémente l’interface IValueConverter. En règle générale, les noms de ces classes se terminent par le nom Converter pour rendre leur objectif clair.
L'interface IValueConverter définit deux méthodes :
Convert: convertit la propriété de la source de liaison en propriété de l’interface utilisateur de la cible de liaison.ConvertBack: convertit la propriété de l’interface utilisateur de la cible de liaison en propriété de la source de liaison.Cette méthode est rarement utilisée et n’est pas utilisée dans ce scénario. La plupart des convertisseurs lèvent une exception
NotSupportedExceptionpour indiquer que cette conversion n’est pas prise en charge.
Voici le contrat de l’interface :
public interface IValueConverter
{
object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture);
object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture);
}
Rappelez-vous que le scénario avec lequel nous travaillons consiste à lier la propriété Entry.BackgroundColor à la propriété de l’objet de données PasswordStrength, qui est une énumération Strength.
<Entry BackgroundColor="{Binding PasswordStrength} ... />
L’énumération Strength doit être convertie en un Color, de sorte que le convertisseur doit évaluer la Strength valeur fournie et retourner une autre Colorvaleur. Le code suivant illustre cette conversion :
namespace MyProject.Converters;
class StrengthToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return (Strength)value! switch
{
Strength.Weak => Colors.OrangeRed,
Strength.Good => Colors.Yellow,
Strength.Strong => Colors.LightBlue,
_ => Colors.LightBlue
};
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
Nous allons décomposer ce code :
- La méthode
Converta quatre paramètres. Vous pouvez généralement ignorer les deux derniers paramètres, sauf si vous avez une raison spécifique de les utiliser. - Le paramètre
valuecontient la valeur entrante. Dans cet exemple, il s’agit d’une valeur d’énumérationStrength. - Le
targetTypeparamètre est ignoré, mais vous pouvez utiliser ce paramètre pour vérifier que le type de propriété avec lequel le convertisseur est utilisé est unColor. Cela est omis dans cet exemple par souci de simplicité. - Une expression switch retourne une couleur différente en fonction de la
Strengthvaleur.
Utilisation du convertisseur en XAML
Une fois la classe de convertisseur créée, vous devez créer une instance de celle-ci et la référencer dans la liaison. La méthode standard pour instancier le convertisseur se trouve dans le dictionnaire de ressources de l’élément racine.
Tout d’abord, mappez un espace de noms XML à l’espace de noms .NET qui contient le convertisseur. Dans l’exemple de code suivant, l’espace de noms XML cvt est mappé à l’espace de noms .NET MyProject.Converters :
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:cvt="clr-namespace:MyProject.Converters"
...
Ensuite, créez une instance dans ContentPage.Resources :
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:cvt="clr-namespace:MyProject.Converters"
x:Class="MyProject.PasswordExample">
<ContentPage.Resources>
<cvt:StrengthToColorConverter x:Key="StrengthToColorConverter" />
</ContentPage.Resources>
À présent, une instance du convertisseur se trouve dans le dictionnaire de ressources avec la clé StrengthToColorConverter, qui se trouve sous le même nom que le type. Il s’agit d’un moyen classique de nommer des convertisseurs, car vous n’avez généralement qu’un seul convertisseur que vous réutilisez tout au long du XAML. Si, pour une raison quelconque, vous avez besoin de plusieurs instances de convertisseur, les clés doivent être différentes entre elles.
Enfin, référencez le convertisseur sur la liaison. Étant donné que le convertisseur se trouve dans un dictionnaire de ressources, vous utilisez l’extension de balisage {StaticResource} pour la référencer. Le convertisseur est affecté à la propriété de liaison Converter :
<Entry BackgroundColor="{Binding PasswordStrength, Converter={StaticResource StrengthToColorConverter}}" ... />