93 votes

L'événement TextBox.TextChanged se déclenche deux fois sur l'émulateur Windows Phone 7

J'ai une application de test très simple pour m'amuser avec Windows Phone 7. J'ai juste ajouté un TextBox et un TextBlock au modèle standard de l'interface utilisateur. Le seul code personnalisé est le suivant :

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private int counter = 0;

    private void TextBoxChanged(object sender, TextChangedEventArgs e)
    {
        textBlock1.Text += "Text changed " + (counter++) + "\r\n";
    }
}

Le site TextBox.TextChanged L'événement est relié à TextBoxChanged dans le XAML :

<TextBox Height="72" HorizontalAlignment="Left" Margin="6,37,0,0"
         Name="textBox1" Text="" VerticalAlignment="Top"
         Width="460" TextChanged="TextBoxChanged" />

Cependant, chaque fois que j'appuie sur une touche lors de l'exécution dans l'émulateur (que ce soit le clavier à l'écran ou le clavier physique, après avoir appuyé sur Pause pour activer ce dernier), le compteur s'incrémente deux fois, affichant deux lignes dans le champ TextBlock . Tout ce que j'ai essayé montre que l'événement est réellement déclenché deux fois, et je ne sais pas pourquoi. J'ai vérifié qu'il n'est souscrit qu'une seule fois - si je me désinscris dans l'événement MainPage rien ne se passe (dans le bloc de texte) lorsque le texte change.

J'ai essayé le code équivalent dans une application Silverlight ordinaire, et le problème ne s'est pas produit. Je n'ai pas de téléphone physique pour reproduire ce problème pour le moment. Je n'ai trouvé aucune trace de ce problème connu dans Windows Phone 7.

Quelqu'un peut-il m'expliquer ce que je fais de mal, ou dois-je le signaler comme un bug ?

EDIT : Pour réduire la possibilité que cela soit dû au fait d'avoir deux contrôles de texte, j'ai essayé de supprimer l'option TextBlock complètement, et en changeant la méthode TextBoxChanged en juste incrémenter counter . J'ai ensuite exécuté dans l'émulateur, tapé 10 lettres et puis mettre un point d'arrêt sur le counter++; (juste pour éliminer toute possibilité que l'entrée dans le débogueur cause des problèmes) - et il affiche counter comme 20.

EDIT : J'ai maintenant demandé dans le forum Windows Phone 7 ... nous verrons ce qui se passe.

0 votes

Par curiosité, si vous vérifiez dans l'événement, le contenu de la boîte de texte est-il le même chaque fois que l'événement se déclenche ? Je ne sais pas vraiment pourquoi cela se produit, car j'utilise habituellement MVVM et la liaison de données au lieu de la gestion des événements pour ces choses (Silverlight et WPF, pas beaucoup d'expérience avec WP7).

0 votes

@Rune : Oui, je vois le texte "après" deux fois. Donc si j'appuie sur "h" et que j'affiche textBox1.Text dans le cadre de l'ajout de textBlock1, il affichera "h" dans les deux lignes.

1 votes

Vous mentionnez les deux claviers, cela pourrait-il être un facteur ? Pouvez-vous en désactiver un ? Et peut-être pouvez-vous vérifier si tous les membres de TextChangedEventArgs sont égaux dans les deux appels ?

77voto

StefanWick Points 2396

La raison pour laquelle le TextChanged Le fait que l'événement se déclenche deux fois dans WP7 est un effet secondaire de la façon dont l'élément TextBox a été modélisé pour le look Metro.

Si vous modifiez le TextBox dans Blend, vous verrez qu'il contient un modèle secondaire. TextBox pour l'état désactivé/en lecture seule. Cela a pour effet secondaire de déclencher deux fois l'événement.

Vous pouvez modifier le modèle pour supprimer le supplément TextBox (et les états associés) si vous n'avez pas besoin de ces états, ou modifiez le modèle pour obtenir un aspect différent dans l'état désactivé/en lecture seule, sans utiliser un élément secondaire TextBox .

Ainsi, l'événement ne se déclenchera qu'une seule fois.

19voto

undertakeror Points 621

J'opterais pour le bug, principalement parce que si vous mettez la KeyDown et KeyUp à cet endroit, il montre qu'ils ne sont déclenchés qu'une seule fois (chacun d'entre eux), mais l'événement TextBoxChanged L'événement est déclenché deux fois

0 votes

@undertakeror : Merci d'avoir vérifié ce point. Je vais poser la même question sur le forum spécifique à WP7 et voir quelle est la réponse...

0 votes

Que fait TextInput ? Cela semble être un gros bug pour passer à travers les tests unitaires de WP7, mais c'est SL.

0 votes

@Chris S : Que voulez-vous dire par "Que fait TextInput faire ?" Je ne suis pas familier avec TextInput ...

8voto

Richard Szalay Points 42486

Cela me semble être un bug. Comme solution de contournement, vous pouvez toujours utiliser la méthode de Rx. DistinctUntilChanged . Il existe une surcharge qui vous permet de spécifier la clé distincte.

Cette méthode d'extension renvoie l'événement TextChanged observable mais ignore les doublons consécutifs :

public static IObservable<IEvent<TextChangedEventArgs>> GetTextChanged(
    this TextBox tb)
{
    return Observable.FromEvent<TextChangedEventArgs>(
               h => textBox1.TextChanged += h, 
               h => textBox1.TextChanged -= h
           )
           .DistinctUntilChanged(t => t.Text);
}

Une fois que le bogue est corrigé, vous pouvez simplement supprimer l'option DistinctUntilChanged ligne.

2voto

crea7or Points 1595

Joli ! J'ai trouvé cette question en cherchant un problème connexe et j'ai également trouvé cette chose ennuyeuse dans mon code. L'événement double consomme plus de ressources CPU dans mon cas. J'ai donc corrigé ma boîte de texte de filtre en temps réel avec cette solution :

private string filterText = String.Empty;

private void SearchBoxUpdated( object sender, TextChangedEventArgs e )
{
    if ( filterText != filterTextBox.Text )
    {
        // one call per change
        filterText = filterTextBox.Text;
        ...
    }

}

1voto

Jerod Houghtelling Points 2426

Je pense que cela a toujours été un bug dans le Compact Framework. Il doit avoir été reporté dans WP7.

0 votes

Je pensais qu'il avait été corrigé dans une version plus récente de la CF... et il serait bizarre d'y entrer malgré le passage à Silverlight. D'un autre côté, c'est un bug assez bizarre à voir de toute façon...

0 votes

Je suis d'accord pour dire que c'est étrange. Je l'ai réexaminé hier dans une application CF 2.0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X