IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Validation : contrôler deux champs à la fois.


Sujet :

Windows Presentation Foundation

  1. #1
    Membre habitué

    Inscrit en
    Février 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut Validation : contrôler deux champs à la fois.
    Bonjour à tous.

    J'ai une vue contenant deux champs :
    Un mot de passe et une vérification de mot de passe.

    Lorsque le mot de passe reste vide, celui-ci demeure inchangé pour un utilisateur même si on lui change des attributs (nom, prénom, adresse, etc.)

    C'est du classique de classique.
    Ce que je voudrais c'est que l'erreur qui s'affiche soit toujours sur le champ vérification.

    Actuellement j'ai un truc dans ce goût là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <!-- Mot de passe -->
    <Label Grid.Column="1"
    	   Grid.Row="3"
    	   Content="Mot de passe :"
    	   VerticalAlignment="Center"/>
    <PasswordBox Grid.Column="2"
    			 Grid.Row="3"
    			 VerticalAlignment="Center"
    			 IsEnabled="True"
    			 x:Name="guiPassword"
    			 DataContext="{Binding RibbonTabUser, Source={StaticResource Locator}}"
    			 local:PasswordHelper.Password="{Binding Path=EditedPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, BindingGroupName=PasswordValidationBindingGroup}"
    			 Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}">
    </PasswordBox>
    <!-- Vérification du mot de passe -->
    <Label Grid.Column="1"
    	   Grid.Row="4"
    	   Content="Vérification :"
    	   VerticalAlignment="Center"/>
    <PasswordBox Grid.Column="2"
    			 Grid.Row="4"
    			 VerticalAlignment="Center"
    			 IsEnabled="True"
    			 x:Name="guiPasswordVerification"
    			 DataContext="{Binding RibbonTabUser, Source={StaticResource Locator}}"
    			 local:PasswordHelper.Password="{Binding Path=EditedPasswordVerification, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, BindingGroupName=PasswordValidationBindingGroup}"
    			 Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}">
    </PasswordBox>
    J'ai des styles qui mettent l'élément en rouge et une astuce (PasswordHelper) sinon je ne peux pas binder le mot de passe car c'est un champ PasswordBox.
    Actuellement :
    • Je tape mon mot de passe (toto). Le champ devient rouge car la vérification est encore vide.
    • Je tape le mot de passe (toto) dans le champ Vérification : le champ vérification passe rouge à la première lettre tappée puis repasse OK lorsque je fini de taper toto
    • Il faut revenir sur le mot de passe puis retaper quelque chose et l'effacer pour que les deux champs soient OK

    Si je ne fais la vérification QUE sur le champ vérification, c'est encore pire, on tape un mot de passe sans vérification et on peut valider (l'activation du bouton save est automatique en fonction du statut du panneau et donc des erreurs de saisie de l'utilisateur, au fils de l'eau) !

    J'ai tenté d'utiliser un BindingGroupName mais ça ne fait pas ce que je veux non plus.

    C'est un cas hyper classique, certains ont une idée, une piste sur comment gérer ça ?

    Merci d'avance.

  2. #2
    Membre expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    J'ai fait un petit truc avec l'interface INotifyDataErrorInfo. C'est hyper simplifié, mais je pense que ça pourrait être une base :

    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow"
            Height="350"
            Width="525"
            Tag="True">
     
     
     
        <StackPanel x:Name="LayoutRoot"
                    Orientation="Vertical"
                    Background="White">
            <TextBox x:Name="TextBox1"
                     Text="{Binding Text1,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=True,UpdateSourceTrigger=PropertyChanged}"></TextBox>
            <TextBox x:Name="TextBox2"
                     Text="{Binding Text2,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=True,UpdateSourceTrigger=PropertyChanged}"></TextBox>
            <Button Content="Save"
                    IsEnabled="{Binding EnableButton}"></Button>
        </StackPanel>
    </Window>

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
        public partial class MainWindow : INotifyPropertyChanged, INotifyDataErrorInfo
        {
            private string _text1;
            private string _text2;
     
            public string Text1
            {
                get { return _text1; }
                set
                {
                    _text1 = value;
                    ValidatePasswords("Text1");
                }
            }
     
            public string Text2
            {
                get { return _text2; }
                set
                {
                    _text2 = value;
                    ValidatePasswords("Text2");
                }
            }
     
            public bool EnableButton { get; set; }
     
     
            public MainWindow()
            {
     
                InitializeComponent();
     
                DataContext = this;
     
            }
     
            private void ValidatePasswords(string propertyname)
            {
                if (Text1 != Text2)
                {
                    HasErrors = true;
                }
                else
                {
                    HasErrors = false;
                }
     
                if (ErrorsChanged != null)
                    ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyname));
     
                EnableButton = !HasErrors;
                OnPropertyChanged("EnableButton");
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            [NotifyPropertyChangedInvocator]
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
     
                var s = handler.GetInvocationList();
     
                foreach (PropertyChangedEventHandler del in s)
                {
                    del(this, new PropertyChangedEventArgs(propertyName));
                }
     
                //if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
     
            public IEnumerable GetErrors(string propertyName)
            {
                Debug.Write("Called");
                return new List<string>();
            }
     
            public bool HasErrors { get; private set; }
            public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
        }

    Quand une propriété texte change, je vérifie si Text1 et Text2 sont identiques. Si oui, c'est bon, sinon je renvoie une erreur.

    Il faudrait renvoyer un message dans GetErrors, et le EnableButton devrait plutôt être un IValueConverter pour que ce soit plus propre.
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  3. #3
    Membre habitué

    Inscrit en
    Février 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Je suis en Framework 4.0, INotifyDataErrorInfo c'est dans le Framwork 4.5.
    Dommage mais l'idée est bonne.
    Mais tu m'as mis sur la bonne piste !
    Plus de groupe, j'ai tout supprimé !
    Une ligne, il me fallait UNE SEULE LIGNE ! WPF est puissant mais souvent on cherche longtemps des trucs tout bête !
    Voici mon code de validation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
            public string this[string _strColumnName]
            {
                get
                {
                    if (UserEditedItem != null)
                    {
                        if (_strColumnName == "EditedPassword")
                        {
                            if (UserEditedItem.UtilisateurID == 0)
                            {   // Si nouvel utilisateur, le mot de passe est requis
                                if (EditedPassword.Length == 0)
                                {
                                    return "Le mot de passe est requis pour créer un nouvel utilisateur";
                                }
                            }
                            // Toujours revérifier le mot de passe de vérification sinon, lorsqu'on édite le mot de passe pour le faire correspondre
                            // à la vérification du mot de passe, même s'ils correspondent, le champ vérification reste en erreur.
                            RaisePropertyChanged("EditedPasswordVerification");
                        }
                        else if (_strColumnName == "EditedPasswordVerification")
                        {
                            if (!EditedPassword.Equals(EditedPasswordVerification))
                            {
                                return "Le vérification du mot de passe est incorrecte";
                            }
                        }
                        else if (_strColumnName == "ListProfilesAssignToEditedUser")
                        {
                            if (ListProfilesAssignToEditedUser.Count == 0)
                            {
                                return "L'utilisateur doit contenir au moins un profile";
                            }
                        }
                        else
                        {
                            try
                            {
                                Validator.ValidateProperty(GetType().GetProperty(_strColumnName).GetValue(this, null), new ValidationContext(this, null, null)
                                {
                                    MemberName = _strColumnName
                                });
                            }
                            catch(Exception ex)
                            {
                                return ex.Message;
                            }
                        }
                    }
     
                    return null; // Pas d'erreur
                }
            }
    L'astuce tellement simple consiste a lancer un RaisePropertyChanged sur la valeur du champ de vérification du mot de passe lorsqu'on vérifie le champ mot de passe (et non pas vérification) => Du coup, il relance une vérification d'erreur sur le champ vérification du mot de passe et c'est celui-ci qui passe en erreur ! Exactement ce que je recherchais, une ligne ! Je suis un peu vert !
    Merci c'est ton code qui m'a mis sur la voie !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ("EditedPasswordVerification");

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Contrôler deux champs liés
    Par supupoff dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 24/03/2010, 11h36
  2. Index deux fois sur deux champs..
    Par Romalafrite dans le forum Requêtes
    Réponses: 0
    Dernier message: 13/06/2008, 10h27
  3. Zend_Form Validation sur deux champs simultanément
    Par sir_gcc dans le forum Zend_Form
    Réponses: 4
    Dernier message: 06/04/2008, 15h20
  4. Valider deux champ de formulaire sans aller côté serveur
    Par tiboudchou dans le forum Struts 2
    Réponses: 1
    Dernier message: 16/10/2007, 18h02
  5. CustomValidator : Validation de deux champs
    Par trihanhcie dans le forum ASP.NET
    Réponses: 9
    Dernier message: 30/03/2007, 12h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo