Ich habe eine sehr einfache Test-App, um mit Windows Phone 7 herumzuspielen. Ich habe gerade ein TextBox
und ein TextBlock
zur Standard-UI-Vorlage hinzugefügt . Der einzige benutzerdefinierte Code ist der folgende:
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";
}
}
Das TextBox.TextChanged
Ereignis ist TextBoxChanged
in der XAML verkabelt :
<TextBox Height="72" HorizontalAlignment="Left" Margin="6,37,0,0"
Name="textBox1" Text="" VerticalAlignment="Top"
Width="460" TextChanged="TextBoxChanged" />
Jedes Mal, wenn ich im Emulator eine Taste drücke (entweder die Bildschirmtastatur oder die physische, nachdem ich Pause gedrückt habe, um letztere zu aktivieren), wird der Zähler zweimal erhöht, wobei zwei Zeilen in der Emulator angezeigt werden TextBlock
. Alles, was ich versucht habe, zeigt, dass das Ereignis wirklich zweimal ausgelöst wird, und ich habe keine Ahnung warum. Ich habe überprüft, dass es nur einmal abonniert wird. Wenn ich mich im MainPage
Konstruktor abmelde , passiert überhaupt nichts (für den Textblock), wenn sich der Text ändert.
Ich habe den entsprechenden Code in einer regulären Silverlight-App ausprobiert und er ist dort nicht aufgetreten. Ich habe im Moment kein physisches Telefon, mit dem ich das reproduzieren kann. Ich habe keine Aufzeichnung darüber gefunden, dass dies ein bekanntes Problem in Windows Phone 7 ist.
Kann jemand erklären, was ich falsch mache, oder sollte ich dies als Fehler melden?
BEARBEITEN: Um die Wahrscheinlichkeit zu verringern, dass dies auf zwei TextBlock
Textsteuerelemente zurückzuführen ist , habe ich versucht, das vollständig zu entfernen und die TextBoxChanged-Methode so zu ändern, dass sie nur inkrementiert wird counter
. Ich habe dann den Emulator ausgeführt, 10 Buchstaben eingegeben und dann einen Haltepunkt in die counter++;
Zeile gesetzt (nur um die Möglichkeit auszuschließen, dass das Einbrechen in den Debugger Probleme verursacht) - und es wird counter
20 angezeigt.
EDIT: Ich habe jetzt im Windows Phone 7-Forum gefragt ... wir werden sehen, was passiert.
quelle
textBox1.Text
als Teil des Zusatzes "textBlock1" anzeige, wird in beiden Zeilen "h" angezeigt .TextChangedEventArgs
hat nicht wirklich viel zur Verfügung - nur dieOriginalSource
, die immer null ist.Antworten:
Der Grund, warum das
TextChanged
Ereignis in WP7 zweimal ausgelöst wird, ist ein Nebeneffekt derTextBox
Vorlage für das Metro-Erscheinungsbild.Wenn Sie die
TextBox
Vorlage in Blend bearbeiten, sehen Sie, dass sie eine sekundäre VorlageTextBox
für den deaktivierten / schreibgeschützten Status enthält. Dies führt als Nebeneffekt dazu, dass das Ereignis zweimal ausgelöst wird.Sie können die Vorlage ändern, um die zusätzlichen
TextBox
(und zugehörigen) Zustände zu entfernen, wenn Sie diese Zustände nicht benötigen, oder die Vorlage ändern, um im deaktivierten / schreibgeschützten Zustand ein anderes Aussehen zu erzielen, ohne einen sekundären zu verwendenTextBox
.Damit wird das Ereignis nur einmal ausgelöst.
quelle
Ich würde mich für den Fehler entscheiden, hauptsächlich, weil, wenn Sie die
KeyDown
undKeyUp
Ereignisse dort einfügen, es zeigt, dass sie nur einmal (jeder von ihnen)TextBoxChanged
ausgelöst werden, aber das Ereignis zweimal ausgelöst wirdquelle
TextInput
?" Ich bin nicht vertraut mitTextInput
...Das klingt für mich nach einem Fehler. Als Problemumgehung können Sie immer Rx verwenden
DistinctUntilChanged
. Es gibt eine Überladung, mit der Sie den eindeutigen Schlüssel angeben können.Diese Erweiterungsmethode gibt das beobachtbare TextChanged-Ereignis zurück, überspringt jedoch aufeinanderfolgende Duplikate:
Sobald der Fehler behoben ist, können Sie einfach die
DistinctUntilChanged
Linie entfernen .quelle
Nett! Ich fand diese Frage, indem ich nach einem verwandten Problem suchte, und fand diese nervige Sache auch in meinem Code. Double Event verbraucht in meinem Fall mehr CPU-Ressourcen. Also habe ich mein Echtzeit-Filtertextfeld mit dieser Lösung repariert:
quelle
Ich glaube, das war schon immer ein Fehler im Compact Framework. Es muss in WP7 übertragen worden sein.
quelle
Sicherlich sieht es für mich nach einem Fehler aus. Wenn Sie versuchen, jedes Mal ein Ereignis auszulösen, wenn sich der Text ändert, können Sie stattdessen eine bidirektionale Bindung verwenden. Leider werden dadurch keine Änderungsereignisse pro Tastendruck ausgelöst (nur wenn das Feld vorhanden ist verliert den Fokus). Hier ist eine Problemumgehung, falls Sie eine benötigen:
quelle
textBlock1.Text
Änderungen ausgelöst wird - ich werde es trotzdem versuchen. (Die Problemumgehung, die ich versuchen wollte, bestand darin, meinen Eventhandler zustandsbehaftet zu machen und sich an den vorherigen Text zu erinnern. Wenn er sich nicht wirklich geändert hat, ignorieren Sie ihn :)Haftungsausschluss - Ich bin mit XAML-Nuancen nicht vertraut und ich weiß, dass dies unlogisch klingt ... aber trotzdem - mein erster Gedanke ist, zu versuchen, nur als einfache Eventargs und nicht als Textchangedeventargs zu gelten. Macht keinen Sinn, aber könnte es helfen? Es scheint, als ob ich solche Doppelschüsse schon einmal gesehen habe, dass dies entweder auf einen Fehler oder auf 2 zusätzliche Event-Handler-Aufrufe zurückzuführen ist, die hinter den Kulissen stattfinden ... Ich bin mir nicht sicher, welche?
Wenn Sie schnell und schmutzig sein müssen, habe ich keine Erfahrung mit xaml. Mein nächster Schritt wäre, xaml für dieses Textfeld als schnelle Problemumgehung zu überspringen. Führen Sie dieses Textfeld vorerst vollständig in c # aus, bis Sie den Fehler oder kniffliger Code ... das heißt, wenn Sie eine temporäre Lösung benötigen.
quelle
Ich glaube nicht, dass es ein Fehler ist. Wenn Sie den Wert einer Texteigenschaft innerhalb des textveränderten Ereignisses zuweisen, wird der Textfeldwert geändert, wodurch das textveränderte Ereignis erneut aufgerufen wird.
Versuchen Sie dies in der Windows Forms-Anwendung. Möglicherweise wird eine Fehlermeldung angezeigt
"In System.Windows.Forms.dll ist eine nicht behandelte Ausnahme vom Typ 'System.StackOverflowException' aufgetreten."
quelle
StefanWick hat recht, erwägen Sie die Verwendung dieser Vorlage
quelle
Es ist ein altes Thema, aber anstatt die Vorlage zu ändern (das funktioniert bei mir nicht, ich sehe das andere Textfeld mit Blend nicht), können Sie einen Booleschen Wert hinzufügen, um zu überprüfen, ob das Ereignis die Funktion bereits ausgeführt hat oder nicht.
Ich bin mir bewusst, dass dies NICHT der perfekte Weg ist, aber ich denke, es ist der einfache Weg, dies zu tun. Und es funktioniert.
quelle