J'ai une application de test très simple pour jouer avec Windows Phone 7. Je viens d'ajouter un TextBox
et un TextBlock
au modèle d'interface utilisateur standard. 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";
}
}
L' TextBox.TextChanged
événement est câblé 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), il incrémente le compteur deux fois, affichant deux lignes dans le TextBlock
. Tout ce que j'ai essayé montre que l'événement se déclenche vraiment deux fois, et je ne sais pas pourquoi. J'ai vérifié qu'il n'est abonné qu'une seule fois - si je me désinscris dans le MainPage
constructeur, rien ne se passe du tout (au bloc de texte) lorsque le texte change.
J'ai essayé le code équivalent dans une application Silverlight standard, et cela ne s'est pas produit là-bas. Je n'ai pas de téléphone physique pour reproduire cela pour le moment. Je n'ai trouvé aucune trace de ce problème connu dans le Windows Phone 7.
Quelqu'un peut-il expliquer ce que je fais mal ou dois-je signaler cela comme un bogue?
EDIT: Pour réduire la possibilité que cela se résume à deux contrôles de texte, j'ai essayé de supprimer TextBlock
complètement le et de changer la méthode TextBoxChanged pour simplement incrémenter counter
. J'ai ensuite exécuté l'émulateur, tapé 10 lettres, puis mis un point d'arrêt sur la counter++;
ligne (juste pour se débarrasser de toute possibilité que le fait de pénétrer dans le débogueur cause des problèmes) - et cela apparaît counter
comme 20.
EDIT: J'ai maintenant demandé dans le forum Windows Phone 7 ... nous verrons ce qui se passe.
la source
textBox1.Text
que j'affiche dans le cadre de l'addition textBlock1, il affichera "h" dans les deux lignes.TextChangedEventArgs
n'a pas vraiment beaucoup de disponible - juste leOriginalSource
, qui est toujours nul.Réponses:
La raison pour laquelle l'
TextChanged
événement se déclenche deux fois dans WP7 est un effet secondaire de la façon dont leTextBox
a été conçu pour le look Metro.Si vous modifiez le
TextBox
modèle dans Blend, vous verrez qu'il contient un secondaireTextBox
pour l'état désactivé / en lecture seule. Cela provoque, comme effet secondaire, l'événement à se déclencher deux fois.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 modifier le modèle pour obtenir un aspect différent dans l'état désactivé / lecture seule, sans utiliser de secondaireTextBox
.Avec cela, l'événement ne se déclenchera qu'une seule fois.
la source
J'irais pour le bogue, principalement parce que si vous mettez les événements
KeyDown
etKeyUp
là-dedans, cela montre qu'ils ne sont déclenchés qu'une seule fois (chacun d'eux) mais l'TextBoxChanged
événement est déclenché deux foisla source
TextInput
-il?" Je ne connais pasTextInput
...Cela me semble être un bug. Pour contourner le problème, vous pouvez toujours utiliser 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:
Une fois le bogue corrigé, vous pouvez simplement supprimer la
DistinctUntilChanged
ligne.la source
Agréable! J'ai trouvé cette question en recherchant un problème connexe et j'ai également trouvé cette chose ennuyeuse dans mon code. Le double événement consomme plus de ressources CPU dans mon cas. J'ai donc corrigé ma zone de texte de filtre en temps réel avec cette solution:
la source
Je pense que cela a toujours été un bogue dans le Compact Framework. Il doit avoir été transféré dans WP7.
la source
Bien sûr, cela ressemble à un bogue pour moi, si vous essayez de déclencher un événement à chaque fois que le texte change, vous pouvez essayer d'utiliser une liaison bidirectionnelle à la place, malheureusement cela ne soulèvera pas d'événements de changement de pression par touche (uniquement lorsque le champ perd le focus). Voici une solution de contournement si vous en avez besoin:
la source
textBlock1.Text
changement - je vais cependant essayer. (La solution de contournement que j'allais essayer était de rendre mon gestionnaire d'événements avec état, en se souvenant du texte précédent. S'il n'a pas réellement changé, ignorez-le :)Clause de non-responsabilité - Je ne suis pas familier avec les nuances xaml et je sais que cela semble illogique ... mais de toute façon - ma première pensée est d'essayer de passer simplement comme des eventargs plutôt que comme des textchangedeventargs. Cela n'a pas de sens, mais peut-être que cela pourrait aider? Il semble que lorsque j'ai déjà vu des doubles déclenchements comme celui-ci, c'est soit à cause d'un bogue, soit à cause de 2 appels de gestionnaire d'événements d'ajout se déroulant dans les coulisses ... Je ne sais pas lequel?
Si vous avez besoin de rapide et de sale, encore une fois, je n'ai pas d'expérience avec xaml - ma prochaine étape serait de simplement ignorer xaml pour cette zone de texte comme solution de contournement rapide ... faites cette zone de texte totalement en c # pour le moment jusqu'à ce que vous puissiez localiser le bogue ou code délicat ... c'est-à-dire si vous avez besoin d'une solution temporaire.
la source
Je ne pense pas que ce soit un bogue. Lorsque vous attribuez la valeur à une propriété de texte à l'intérieur de l'événement textchanged, la valeur de la zone de texte est modifiée, ce qui appellera à nouveau l'événement text changed.
essayez ceci dans l'application Windows Forms, vous pourriez obtenir une erreur
«Une exception non gérée de type 'System.StackOverflowException' s'est produite dans System.Windows.Forms.dll»
la source
StefanWick a raison, pensez à utiliser ce modèle
la source
C'est un vieux sujet, mais au lieu de changer de modèle (cela ne fonctionne pas pour moi, je ne vois pas l'autre zone de texte avec Blend), vous pouvez ajouter un booléen pour vérifier si l'événement a déjà rempli la fonction ou non.
Je suis conscient que ce n'est PAS le moyen idéal, mais je pense que c'est le moyen le plus simple de le faire. Et il fonctionne.
la source