WinRT XAML : Une solution simple pour la validation des données

Dans le cas des applications WinRT, les mécanismes de validation de données ne sont pas encore aussi évolués que dans d’autres technologies qui ont plus de vécu.

Voici comment palier à ce manque avec un toolkit qui réserve certainement encore bien d’autres bonnes surprises : WinRT XAML Toolkit. Il est utilisable aussi bien sur Windows 8.0 que sur 8.1.

Cet article détaille un exemple de ce qu’il permet de réaliser très facilement et rapidement tout en étant compatible avec les mécanismes de traduction natifs de la plateforme pour XAML (x:Uid).

Pour un champ de saisie, on pourra définir:

  • une combinaison de formats à respecter parmi:
    • Any
    • EqualsPattern
    • IncludesDigits
    • IncludesLowercase
    • IncludesSymbol
    • IncludesUppercase
    • IsStrongPassword
    • MatchesRegexPattern
    • MinLength
    • NoDoubles
    • NonEmpty
    • NonEmptyNumeric
    • Numeric
    • SpecificLength
  • des messages d’erreur associés à l’état courant de la zone de saisie, en fonction du format choisi
  • une couleur de fond sur erreur de validation
  • une couleur de fond sur un champ valide

settings

Installation du WinRT Xaml Toolkit via nuget

Commençons donc par installer ce fameux toolkit aussi disponible via nuget. Pour cela, accédez aux packages de l’application en faisant un click droit sur le projet et sélectionnez “Manage NuGet Packages”:

image

Sélectionnez les packages Online à gauche, puis dans la zone de recherche, tapez “winrt xaml toolkit” : le premier résultat de recherche sera en principe le bon.

image

Mise en place de la validation des données pour une TextBox

Dans votre fichier xaml, ajouter le namespace relatif au toolkit :

xmlns:xamltk="using:WinRTXamlToolkit.Controls.Extensions"

Puis, sur votre TextBox, ajoutez les propriétés qui vous permettront de personnaliser la validation.

La propriété la plus importante est le format, qui peut prendre une combinaison des valeurs suivantes (utiliser la virgule pour les combiner):

  • Any
  • EqualsPattern
  • IncludesDigits
  • IncludesLowercase
  • IncludesSymbol
  • IncludesUppercase
  • IsStrongPassword
  • MatchesRegexPattern
  • MinLength
  • NoDoubles
  • NonEmpty
  • NonEmptyNumeric
  • Numeric
  • SpecificLength

Puis, il sera complété par d’autres propriétés relatives au format comme nous le verrons dans les exemples ci-dessous.

Exemple 1 : Champ numérique non vide

Dans mon cas, je souhaite une valeur numérique non nulle, je spécifie donc le format NonEmptyNumeric ainsi que 2 messages d’erreurs selon que le champ soit vide ou non numérique avec NumericErrorMessage et NonEmptyErrorMessage. Je spécifie également une couleur de fond pour la TextBox en cas d’erreur.

Voici le code correspondant pour ma TextBox. Signalons qu’elle profite de la nouvelle propriété Header qui m’évite de créer un contrôle supplémentaire pour l’affichage du titre du champ de saisie.

<TextBox x:Name="tbPort" x:Uid="GeneralSettingsFlyout_Port" Header="Port"
           Width="100"
           HorizontalAlignment="Left"
           Text="{Binding Port, Mode=TwoWay}"
           xamltk:FieldValidationExtensions.Format="NonEmptyNumeric"
           xamltk:FieldValidationExtensions.NumericErrorMessage="Ce numro de port n'est pas valide"                    
           xamltk:FieldValidationExtensions.NonEmptyErrorMessage="Cette information est obligatoire"
           xamltk:FieldValidationExtensions.InvalidBrush="{StaticResource BackErrorColor}"
/>

Remarquez que les messages d’erreur sont en dur : nous verrons comment faire référence au dictionnaire de ressources dans la suite de l’article.

L’affichage des messages d’erreur se fera dans un TextBlock dont le contenu est bindé au ValidationMessage de la TextBox. Ce message variera automatiquement en fonction de la valeur du champ de saisie.

<TextBlock TextWrapping="WrapWholeWords"
           Style="{StaticResource ValidationErrorLabelStyle}"
           Text="{Binding (xamltk:FieldValidationExtensions.ValidationMessage), ElementName=tbPort}"
           />

Pour finir, voici un exemple de style appliqué au TextBlock avec ValidationErrorLabelStyle:

<SettingsFlyout.Resources>
    <Style
       x:Key="ValidationErrorLabelStyle"
       TargetType="TextBlock">
        <Setter
           Property="Foreground"
           Value="{StaticResource HighlightColorLow}" />
        <Setter
           Property="FontSize"
           Value="12" />
        <Setter
           Property="Margin"
           Value="3" />
    </Style>
    <SolidColorBrush x:Key="BackErrorColor" Color="#8486C7"/>
</SettingsFlyout.Resources>

Traduction des messages d’erreur

Pour utiliser le nouveau mécanisme de traduction introduit avec Windows 8, attribuons un x:Uid à la TextBox et alimentons le fichier de ressources avec les couples [Uid.propriété, chaine de caractère traduite]. Jusque là rien de plus normal. La seule subtilité vient de la notation pour référencer le namespace dans lequel sont définies les propriétés qui nous intéressent et qui proviennent du toolkit.

Ainsi dans mon exemple, le fichier Strings ressemblera à cela :

image

Exemple 2 : Champ non vide validé par une expression régulière

Voici un autre exemple avec un champ qui doit être non vide et respecter une expression régulière:

<TextBox x:Name="tbNAS" x:Uid="GeneralSettingsFlyout_NASAddress" Header="NAS Address"
       Text="{Binding ServerAddress, Mode=TwoWay}"
       xamltk:FieldValidationExtensions.Format="MatchesRegexPattern"
       xamltk:FieldValidationExtensions.Pattern="(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0..."
       xamltk:FieldValidationExtensions.PatternErrorMessage="Not an Uri"                    
       xamltk:FieldValidationExtensions.InvalidBrush="{StaticResource BackErrorColor}"/>

<TextBlock TextWrapping="WrapWholeWords"
       Style="{StaticResource ValidationErrorLabelStyle}"
       Text="{Binding (xamltk:FieldValidationExtensions.ValidationMessage), ElementName=tbNAS}" />

Autre option : vous pourrez rendre le TextBlock d’erreur visible ou non selon que le champ de saisie soit en erreur ou non. Pour cela, il faut binder la propriété Visibility du TextBlock, à la propriété ValidationMessageVisibility de la TextBox.

Exemple:

<TextBlock
   Style="{StaticResource ValidationErrorLabelStyle}"
   Text="{Binding (extensions:FieldValidationExtensions.ValidationMessage), ElementName=NonEmptyTextBox}"
   Visibility="{Binding (extensions:FieldValidationExtensions.ValidationMessageVisibility), ElementName=NonEmptyTextBox}"/>

En espérant que cela vous rendra la vie validation plus simple…