Event lost focus appelé en boucle

Event lost focus appelé en boucle - C#/.NET managed - Programmation

Marsh Posté le 20-02-2011 à 22:54:03    

Je débute en C#, pour vérifier qu'une textbox ne contient une valeur numérique j'utilise le code suivant :

Code :
  1. private void check_value(object sender)
  2.         {
  3.             TextBox tb = (TextBox)sender ;
  4.             MessageBoxResult result;
  5.             if (!Utility.isNumeric(tb.Text)){
  6.                 result = MessageBox.Show("Vous ne pouvez entrer que des chiffres" );
  7.                 tb.Focus();
  8.             }
  9.         }
  10. private void Amount_1_LostFocus(object sender, RoutedEventArgs e)
  11.         {
  12.             check_value(sender);
  13.                
  14.         }
 

Problème, quand la valeur contient une lettre, l'event Lostfocus de la textbox est appelé en boucle et je ne comprends pas pourquoi vu que je lui donne le focus juste avant...


Message édité par LePhasme le 21-02-2011 à 04:47:02

---------------
Instagram - Mon PVT en Australie.
Reply

Marsh Posté le 20-02-2011 à 22:54:03   

Reply

Marsh Posté le 21-02-2011 à 13:44:02    

Je dirais au premier coup d'oeil que tu ne précises pas, dans ton Amount_1_LostFocus, que l'événement est consommé ou non selon le test fait dans check_value.
 
(je ne sais plus s'il y a un e.Handled avec LostFocus, mais c'est dans l'esprit).
 
Donc il repart pour un tour (en gros).
 
Autres remarques :
L'intérêt d'avoir une méthode à part (check_value) me paraît aussi assez limité dans ton cas, vu que tu castes explicitement ton sender en TextBox...  
Autant tout faire dans Amount_Lost_Focus dans ce cas-là (tu peux appliquer la même méthode à plusieurs TextBox - ou, pour être plus précis mais moins clair, donner la même méthode en paramètre à plusieurs délégués avec la même signature liés à des TextBox différents).
 
Pas besoin de passer par MessageBoxResult : tu ne fais rien de result...
Un MessageBox.Show("xxx" ) te suffit pour un message d'avertissement.
 
Cela mis à part, je préfère (est-ce rationnel) utiliser des événements validated ou validating pour ce genre de choses. Mais bon ça dépend de l'usage.
 
 

Reply

Marsh Posté le 22-02-2011 à 00:53:23    

J'ai essayé de rajouter un e.handled = true dans le lostfocus mais ça n'a rien changé. :/
 
J'utilisais une méthode à part parce que j'ai plusieurs champs et j'aurais juste à ajouter l'appel à la méthode dans le lostFocus des autres champs quand j'aurais réussi à trouver la cause du problème.
Mais effectivement ce serait sans doute plus propre d'utilisé un delegate.
 
Je n'ai pas d'évènement validated/validating attaché à ma textbox.


---------------
Instagram - Mon PVT en Australie.
Reply

Marsh Posté le 22-02-2011 à 10:50:07    

Edit : tu fais du c#, mais quel techno, quel version du framework, en fait ?
 
 

LePhasme a écrit :

J'ai essayé de rajouter un e.handled = true dans le lostfocus mais ça n'a rien changé. :/
 
J'utilisais une méthode à part parce que j'ai plusieurs champs et j'aurais juste à ajouter l'appel à la méthode dans le lostFocus des autres champs quand j'aurais réussi à trouver la cause du problème.
Mais effectivement ce serait sans doute plus propre d'utilisé un delegate.
 
Je n'ai pas d'évènement validated/validating attaché à ma textbox.


 
Bon :
Pour chaque TextBox

Code :
  1. myTextBox.Validating += new CancelEventHandler(this.ValidatingTextBox);
  2. myTextBox2.Validating += new CancelEventHandler(this.ValidatingTextBox);


Tu n'as pas besoin d'avoir une méthode Validating_TextBox
et une autre Validating_TextBox1 !
 
Ensuite

Code :
  1. public void ValidatingTextBox(object sender, CancelEventArgs e) {
  2. TextBox tb = (TextBox)sender;
  3. if (!Utility.isNumeric(tb.Text)) {
  4. tb.Text = string.Empty; // eventuellement, tu nettoies ta boîte
  5. MessageBox.Show("Vous ne pouvez entrer que des chiffres" );
  6. e.Cancel = true;
  7. }
  8. }


Message édité par deliriumtremens le 22-02-2011 à 11:02:19
Reply

Marsh Posté le 22-02-2011 à 11:12:19    

Ah ouais, tu fais du WPF ^^
 
Bon ben tu n'as pas de validating, c'est sûr.
 
Mais la logique devrait rester presque la même
 

Code :
  1. myTextBox.LostFocus+= new RoutedEventHandler(this.TextBoxLostFocus); // je suppose qu'il s'agit d'un RoutedEventHandler ??
  2. myTextBox2.LostFocus+= new RoutedEventHandler(this.TextBoxLostFocus);
  3. ...
  4. myTextBox2354.LostFocus += new RoutedEventHandler(this.TextBoxLostFocus);


 

Code :
  1. public void TextBoxLostFocus(object sender, RoutedEventArgs e) {
  2.     TextBox tb = (TextBox)sender;
  3.     int val;
  4.     if(!Utility.IsNumeric(tb.Text)) {
  5.         tb.Text =string.Empty;//vidage éventuel
  6.         e.Handled = true;
  7.         MessageBox.Show("erreur" );
  8.         //tu n'as pas besoin de refaire un Focus
  9.     }
  10. }


Message édité par deliriumtremens le 22-02-2011 à 11:16:25
Reply

Marsh Posté le 22-02-2011 à 11:42:20    

Ah, ben testé, ça marche à peu près, mais on perd le focus...
 
Le mieux serait peut-être donc de faire plutôt un TextBoxChanged
 
(La même méthode pour toutes tes Textbox, on l'aura compris).

Code :
  1. private void TextBoxTextChanged(object sender, TextChangedEventArgs e)
  2.         {
  3.             TextBox tb = (TextBox)sender;
  4.             double val;
  5.             if (tb.Text.Length > 0 && !Double.TryParse(tb.Text, out val))
  6.             {
  7.                 MessageBox.Show("erreur" );
  8.                 tb.Text = string.Empty;//bourrin, mais ça évite de garder des saletés.
  9.             }
  10.         }


Message édité par deliriumtremens le 22-02-2011 à 11:46:59
Reply

Marsh Posté le 23-02-2011 à 01:26:17    

Le problème c'est qu'effacer tout pour une erreur de frappe c'est franchement moyen...
Du coup je vais essayer de passer par des bindings validations vu que c'est une application pour apprendre de toute façon...

 

Un grand merci pour tes réponses :)


Message édité par LePhasme le 23-02-2011 à 01:26:47

---------------
Instagram - Mon PVT en Australie.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed