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

Vos contributions VB6 Discussion :

Ne pas utiliser CausesValidation / Validate [Infos]


Sujet :

Vos contributions VB6

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 50
    Points : 36
    Points
    36
    Par défaut Ne pas utiliser CausesValidation / Validate
    Ne pas utiliser CausesValidation / Validate


    Bonjour,

    bizarrement, c'est pas une question que je pose, mais j'apporte plutôt un élément de réponse à ceux qui se poseraient celle que je me suis posé ...
    Je vais être plus clair !

    J'ai un formulaire comportant des champs de type TextBox.
    A chaque sortie, je veux valider la saisie afin de bloquer le passage au control suivant. Il me faut donc intervenir avant le passage de focus.
    Je ne passe donc pas par les événements lostfocus/gotfocus.

    En effet, comment empêcher le changement de focus si le test est effectué APRES le changement ?
    Ne me répondez pas qu'il suffit de faire un setfocus dans le champ qui a reçu le focus, car si ce 2eme control possède également une méthode de control de saisie dans son événement lostfocus, on arrive sur des cas de boucles sans fin trés vite.
    A moins d'imaginer un système de verrou, qui n'éxécute le test qu'à condition que le champ précédent a été validé ... mais c'ests trés lourd à gérer, et on se met à réinventer la poudre.

    L'événement Validate semble en effet tout indiqué pour répondre à la problématique.
    Je vous copie tels quels qques passages trés intéressants et explicites trouvés sur le net :

    Événement Validate des contrôles
    Les contrôles génèrent aussi un événement Validate qui est déclenché avant que le contrôle ne perde le focus. Toutefois, cet événement survient uniquement lorsque la propriété CausesValidation du contrôle sur le point de recevoir le focus est à True. Dans de nombreux cas, l'événement Validate est plus approprié que l'événement LostFocus pour la validation des données parce qu'il survient avant la perte du focus. Pour plus d'informations, reportez-vous à la section « Validation de l'entrée d'un contrôle par restriction du focus » du chapitre 7, « Utilisation des contrôles standard de Visual Basic ».
    Validation des données de contrôle par restriction du focus

    L'événement Validate et la propriété CausesValidation sont utilisés de paire pour vérifier l'entrée d'un contrôle avant d'autoriser l'utilisateur à le désactiver. Prenons, par exemple, une application contenant plusieurs zones de texte et un bouton Aide. Lorsque chaque zone de texte reçoit le focus, vous devez empêcher les utilisateurs de déplacer ce focus tant que les critères de validation spécifiques de la zone de texte ne sont pas remplis. Toutefois, vous devez également autoriser les utilisateurs à cliquer sur le bouton Aide à tout moment. Pour cela, vous devez affecter la valeur False au critère de validation de l'événement Validate ainsi qu'à la propriété CausesValidation du bouton Aide. Si la propriété a la valeur True (paramètre par défaut), l'événement Validate interviendra sur le premier contrôle. En revanche, si elle a la valeur False, l'événement Validate affecté au premier contrôle n'interviendra pas.

    L'événement Validate est mieux adapté à la validation de saisie de données que l'événement LostFocus parce que, par définition, l'événement LostFocus intervient une fois le focus déplacé. En revanche, l'événement Validate vous permet d'empêcher le déplacement du focus vers un autre contrôle tant que toutes les conditions de validation ne sont pas remplies.
    J'avais donc trouver une solution ... LA solution !
    Mais mes jolis espoirs se sont vite envolé...


    En effet, je me suis aperçu que dans certains cas, l'événement validate ne se déclenchait pas... J'ai d'abord pensé à une erreur de code de ma part, puis à une mauvaise initialisation des propriétés des controles de mon formulaire... Mais j'ai du me rendre à l'évidence : l'événement validate n'est pas fiable !

    J'ai donc cherché à en savoir plus, et je suis tombé sur un article de microsoft édifiant, constatant effectivement et officiellement le bug.

    A cette adresse http://support.microsoft.com/search/...og=LCID%3D1036 on apprend ceci :

    BUG: CausesValidation Property Does Not Trigger Validate Event

    SYMPTOMS
    The Validate event of a control is not executed when it loses focus to another control that has its CausesValidation property set to True.

    STATUS
    Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

    MORE INFORMATION
    Microsoft Visual Basic 6.0 introduced a new Boolean property called CausesValidation on various controls, such as the TextBox. According to Visual Basic Help, when there is an attempt to put focus on a control that has its CausesValidation property set to True, the Validate event of the control that is losing focus executes. During that Validate event, you can verify that the data entered is valid and you can prevent the shift of focus to the new control if you want.
    On y trouve d'ailleurs un exemple permettant de reproduire le bug !
    1. Create a new Standard EXE project. Form1 is created by default.
    2. Add three TextBox controls to Form1.
    3. Set the CausesValidation property in Text1 and Text3 to True.
    4. Set the CausesValidation property in Text2 to False.
    5. Paste the following code into Form1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     Private Sub Text1_Validate(Cancel As Boolean)
             Debug.Print "Text1's Validate Event"
          End Sub
     
          Private Sub Text2_Validate(Cancel As Boolean)
             Debug.Print "Text2's Validate Event"
          End Sub
     
          Private Sub Text3_Validate(Cancel As Boolean)
             Debug.Print "Text3's Validate Event"
          End Sub
    Run the sample project.
    7. The focus begins on Text1. Click Text3. The CausesValidation property of Text3, set to True, causes the Validate event of Text1 to be executed as expected.
    8. With the focus on Text3, click Text2. The CausesValidation property of Text2, set to False, does not cause the Validate event of Text3 as expected.
    9. With the focus on Text2, click Text3. The CausesValidation property of Text3, set to True, does not cause the Validate event of Text2 as it should.

    With the CausesValidation property of Text2 set to False, there does not appear to be any way to get a Validate event for Text2 to execute.

    Aside from attempting to use the LostFocus event to manually call a Validate event for Text2 from Text2, you can work around this problem by changing the CausesValidation property from False to True.
    Nous y sommes chers amis ! La validation des données ne passera pas par le CausesValidation ...

  2. #2
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Points : 4 674
    Points
    4 674
    Par défaut
    Je ne comprends pas du tout où est le problème !
    Ce qui marche très bien et tout simplement :

    Vérification (contrôle) de la saisie dans l'événement Lostfocus de la textBox
    et :
    - si satisfait, on laisse passer à la textbox logique suivante
    - si pas satisfait : setfocus sur la textbox non satisfaite (sur elle-même, donc). Et ceci marche sans problème !... C'est tout.

  3. #3
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Mais si le controle possède une méthode GetFocus, le fait de lui faire une SetFocus va appeler inutilement cette méthode. Ce qui peut amené à des boucles comme cité plus haut

  4. #4
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Points : 4 674
    Points
    4 674
    Par défaut
    Citation Envoyé par Tofalu
    Mais si le controle possède une méthode GetFocus, le fait de lui faire une SetFocus va appeler inutilement cette méthode. Ce qui peut amené à des boucles comme cité plus haut
    Que faut-il répondre à celà ?

    On y va donc, pas à pas :

    1) il n'existe aucune méthode Getfocus
    2) une méthode est ce que l'on décide de mettre en oeuvre, pas ce que l'on subit
    3) un événement est ce que l'on subit par contre
    4) il n'existe aucun événément getfocus. Il y a un événement Gotfocus, par contre, qui est constaté lorsqu'un contrôle obtient le focus.
    5) je veux me contenter ici de VB, voulant (bien que les choses y soient les mêmes), ignorer temporairement les autres langages de développement... car nous sommes ici sous VB !
    6) un contrôle obtient le focus de différentes manières, en passant par l'utilisation de la souris... mais également en utilisant le tabulateur... mais aussi de façon dynamique (par code, donc)
    7) Je n'ai pas réussi, personnellement, à provoquer la boucle à laquelle on fait ici allusion, boucle qui devrait considérer, donc, qu'un setfocus provoqué dynamiquement n'aurait pas rigoureusement les mêmes réactions qu'un setfocus (générant donc un événement gotfocus) provoqué autrement.

    Dans le plus grand respect de VB, je demande donc à Tofalu de nous donner ici un exemple concret (avec le code correspondant, bien évidemment...) de ce qu'il entend par ce qu'il a affirmé. Celà aura au moins le mérite d'argumenter autrement que par des mots la justesse de ce que l'on dit.

    Je le remercie d'avance pour ce que m'apportera son précieux exemple.

  5. #5
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    Citation Envoyé par jmfmarques
    Dans le plus grand respect de VB, je demande donc à Tofalu de nous donner ici un exemple concret (avec le code correspondant, bien évidemment...) de ce qu'il entend par ce qu'il a affirmé. Celà aura au moins le mérite d'argumenter autrement que par des mots la justesse de ce que l'on dit.

    Je le remercie d'avance pour ce que m'apportera son précieux exemple.
    Ma modeste contribution
    Sur une feuille, 2 textebox
    l'idée est de ne saisir que des valeurs numeriques
    donc dans le lost focus , on ramene le focus si le contenu n'est pas numérique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Private Sub Text1_LostFocus()
      If Not IsNumeric(Text1) Then
        Text1.SetFocus
      End If
    End Sub
    Private Sub Text2_LostFocus()
      If Not IsNumeric(Text2) Then
        Text2.SetFocus
      End If
    End Sub
    En fait le probleme qui se passe, c'est le second textbox recoit le focus avant que le premier aie déclenché son lost focus. quand le premier ramene le focus, le second dit, dans son lostfocus, pas d'accord revient ici . le premier dit pas d'accord, revient ici : on boucle sans fin.
    En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
    (ALEXANDRE DUMAS)

    N'hésitez pas à visiter ma page de contributions

  6. #6
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Points : 4 674
    Points
    4 674
    Par défaut
    je viens de lire l'exposé de cette difficulté .... et... en reste baba ...

    bon... alors et puisqu'il faut tout dire : une très vieille méthode (parmi une bonne dizaine d'autres...: juste un peu de gymnastique)
    j'avais mis celle-ci en oeuvre pour faire face à une difficulté du même genre avec..... Word Basic !!! (voilà qui n'est pas daté d'hier !!!!)

    la seule syntaxe complémentaire que requiert chaque textbox dont la saisie est "contrôlée" se résume à "If titi then exit sub" ....(c'est peu...)

    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
    Private laisse As Boolean
     
    Private Sub Text1_LostFocus()
      If titi Then Exit Sub
      If Not IsNumeric(Text1.Text) Then toto Text1 ' ou bien évidemment tout autre type de vérification
    End Sub
     
    Private Sub Text2_LostFocus()
     If titi Then Exit Sub
     If Not IsNumeric(Text2.Text) Then toto Text2 ' ou bien évidemment tout autre type de vérification
    End Sub
     
    Private Sub Text3_LostFocus()
     If titi Then Exit Sub
     If Not IsNumeric(Text3.Text) Then toto Text3 ' ou bien évidemment tout autre type de vérification
    End Sub
     
    Private Sub Text4_LostFocus()
     If titi Then Exit Sub
     If Not IsNumeric(Text4.Text) Then toto Text4 ' ou bien évidemment tout autre type de vérification
    End Sub
     
    'etc...
    'etc....
    'Private Sub Textn_LostFocus()
    ' If titi Then Exit Sub
    ' If Not IsNumeric(Textn.Text) Then toto Textn
    'End Sub
     
    Sub toto(machin)
      machin.SetFocus
      laisse = True
    End Sub
     
    Function titi() As Boolean
      If laisse Then
       laisse = False: titi = True
      Else
       titi = False
      End If
    End Function
    je vous laisse deviner ce que donne cette méthode si l'on utilise astucieusement un groupe de textboxes indéxées !....(encore plus simple)

  7. #7
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    Personellement, jutilise un variable niveau feuille
    Ce qui donne

    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
     
    Dim ForcedFocus as Boolean
     
    Private Sub Text1_LostFocus()
      If ForcedFocus Then Exit Sub ' Si on entre ici  par programme
      If Not IsNumeric(Text1) Then
        ForcedFocus  = True  'on met la variable a True
        Text1.SetFocus        'on rapatrie le focus
        Doevents                'laisse windows gérer les evenements
        ForcedFocus = False
      End If
    End Sub
    Private Sub Text2_LostFocus()
      If ForcedFocus Then Exit Sub ' Si on entre ici  par programme
      If Not IsNumeric(Text2) Then
        ForcedFocus  = True  'on met la variable a True
        Text2.SetFocus
        Doevents                'laisse windows gérer les evenements
        ForcedFocus = False
      End If
    End Sub
    Ta solution est plus elegante encore, chapeau. mais je n'aime pas trop ton nomage de fonction lol
    En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
    (ALEXANDRE DUMAS)

    N'hésitez pas à visiter ma page de contributions

  8. #8
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Points : 4 674
    Points
    4 674
    Par défaut
    Le nommage ?
    Ben,... titi et toto sont mes potes habituels...
    Sinon, il y a aussi Zorro, Tarzan, Marius, Olive, Popeye etc...

  9. #9
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    J'aurais plutot vu NonReviens à la place de toto
    En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
    (ALEXANDRE DUMAS)

    N'hésitez pas à visiter ma page de contributions

  10. #10
    Modérateur
    Avatar de AlainTech
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mai 2005
    Messages
    4 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2005
    Messages : 4 235
    Points : 24 327
    Points
    24 327
    Par défaut
    Petite contribution concernant les Lost/Got Focus.

    Le comportement est très différent en fonction du langage.
    Dans l'ordre, du plus pauvre au plus complet:

    VB6
    Les événements LostFocus et GotFocus existent sous ces noms-là.
    GotFocus est intercepté après l'événement LostFocus.
    Pas de possibilité de Cancel.
    Attention, pour faire le test de succession des événements, il ne faut pas utiliser de Msgbox (ce dernier "attrapant" le focus) mais bien Debug.Print.

    VBA-E
    Les événements portent respectivement les noms de _Exit et _Enter.
    L'événement Exit est activé avant le Enter suivant et il possède une variable Cancel qui permet de retourner au contrôle quitté.

    VBA-A
    Quatre événements peuvent être interceptés: Exit, Enter, GotFocus et LostFocus.
    Pour un passage entre deux contrôles, ils se succèdent dans l'ordre suivant:
    Exit, LostFocus, Enter et enfin, GotFocus.
    L'événement Exit possède un Cancel.

    Excel et Access se "fichent" pas mal d'un Msgbox dans les procédures événementielles. Le Msgbox ne pique pas le focus aux contrôles.

    Word se comporte comme Excel et je n'ai pas cherché dans les autres applications Office.
    N'oubliez pas de cliquer sur quand vous avez obtenu ou trouvé vous-même la réponse à votre question.
    Si vous trouvez seul, pensez à poster votre solution. Elle peut servir à d'autres!
    Pensez aussi à voter pour les réponses qui vous ont aidés.
    ------------
    Je dois beaucoup de mes connaissances à mes erreurs!

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/03/2013, 12h47
  2. []Validate / CausesValidation => Ne pas utiliser
    Par Gildas Huart dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 11/08/2005, 10h55
  3. l'executable n'est pas une win32 valide
    Par joebilou dans le forum Windows
    Réponses: 4
    Dernier message: 28/06/2005, 11h53
  4. Réponses: 10
    Dernier message: 30/11/2004, 10h12
  5. [XHTML] IE ne lit pas mon document valide
    Par Invité4 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 31/10/2004, 14h10

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