2010-06-24 6 views
8

Ich habe eine TextBox mit einem TextChanged Ereignis verdrahtet. Am Ende wird eine Abfrage an eine SQL-Datenbank gestellt, daher möchte ich die Anzahl der Abfragen begrenzen.Wie behandelt man das TextChanged-Ereignis nur, wenn der Benutzer mit der Eingabe aufhört?

Ich möchte nur die Abfrage machen, wenn der Benutzer keinen Schlüssel in sagen .. 300 Millisekunden oder so gedrückt hat. Wenn aus irgendeinem Grund die vorherige Abfrage noch ausgeführt wird, müsste ich dies abbrechen und dann eine neue Abfrage ausgeben.

Antwort

8

Erstellen Sie einen System.Windows.Forms.Timer und setzen Sie ihn nach jedem Tastendruck zurück (z. B. stoppen und dann starten). Wenn das Timer-Ereignis ausgelöst wird, deaktivieren Sie den Timer.

+0

Dies ist die Methode, die ich verwendet habe und es hat perfekt funktioniert. Überraschenderweise bekomme ich keine Ausnahmen, dass die Benutzeroberfläche von einem anderen Thread aktualisiert wird. – esac

+0

Siehe http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S1. Die kurze Antwort lautet, dass das Ereignis im UI-Thread ausgeführt wird. Was sinnvoll ist, wenn man bedenkt, dass es sich um den Namensraum 'System.Windows.Forms' handelt. – Brian

+0

Beachten Sie, dass der oben genannte Link zum MSDN-Magazin keine direkte Verbindung mehr ist. Sie können weiterhin mit [archive.org] (https://web.archive.org/web/20130219050936/http://msdn.microsoft.com/en-us/magazine/cc164015.aspx) darauf zugreifen. Oder laden Sie einfach das Magazin vom Februar 2004 von dieser Seite herunter. Wenn Sie keinen CHM-Leser haben, können Sie auf den Artikel zugreifen, indem Sie die CHM-Datei mit 7zip extrahieren und '/ MSDNMagazineFebruary2004en-us/TimersinNET/chm.htm' öffnen – Brian

0

Fügen Sie einen zweiten actionlistener hinzu, der immer dann aufgerufen wird, wenn der Benutzer eine beliebige Taste drückt, und wenn er aufgerufen wird, speichert er die aktuelle Zeit in einer globalen Variablen. Wann immer Ihr TextChanged-Ereignis aufgerufen wird, überprüft es den Zeitunterschied zwischen der globalen Variablen und der aktuellen Zeit.

Wenn der Unterschied weniger als 300 Millisekunden beträgt, starten Sie einen Zeitgeber, um die Abfrage nach 300 Millisekunden auszuführen. Wenn der Benutzer dann eine andere Taste drückt, setzt er den Timer zuerst zurück.

+0

Das erfordert, dass der Benutzer 300ms wartet und dann ein anderes Zeichen eingibt, wenn sie Ergebnisse senden möchten. – Brian

1

Verwenden Sie das Reactive Framework, um eine Folge von Ereignissen auszulösen. Ich bin mir nicht sicher genau wie das funktionieren würde, aber Sie können es hier (Reactive Extensions for .NET) nachlesen und sehen, ob es Ihre Bedürfnisse erfüllen wird. Auch hier gibt es einige Beispiele: Examples. Das "Throttling" -Beispiel ist möglicherweise das, wonach Sie suchen.

0

1) Erstellen Sie einen Timer.

2) Erstellen Sie einen Handler für das Tick-Ereignis Ihres Timers. Überprüfen Sie bei jedem Häkchen, ob genügend Leerlaufzeit verstrichen ist. Ist dies der Fall, STOPPEN Sie den Timer und führen Sie die Abfrage aus.

3) Immer wenn ein Tastendruck in dieser Textbox auftritt, NEUSTACHTEN Sie den Timer.

1

Dank @ Brians Idee und this answer, kam ich mit meiner eigenen Version des Verwendens eines Timers, um dieses Problem zu behandeln. Das hat gut für mich funktioniert. Ich hoffe, dass es den anderen auch hilft:

private Timer _tmrDelaySearch; 
private const int DelayedTextChangedTimeout = 500; 
private void txtSearch_TextChanged(object sender, EventArgs e) 
{ 
    if (_tmrDelaySearch != null) 
    _tmrDelaySearch.Stop(); 

    if (_tmrDelaySearch == null) 
    { 
     _tmrDelaySearch = new Timer(); 
     _tmrDelaySearch.Tick += _tmrDelaySearch_Tick; 
     _tmrDelaySearch.Interval = DelayedTextChangedTimeout; 
    } 

    _tmrDelaySearch.Start(); 
} 

void _tmrDelaySearch_Tick(object sender, EventArgs e) 
{ 
    if (stcList.SelectedTab == stiTabSearch) return; 
    string word = string.IsNullOrEmpty(txtSearch.Text.Trim()) ? null : txtSearch.Text.Trim(); 

    if (stcList.SelectedTab == stiTabNote) 
    FillDataGridNote(word); 
    else 
    { 
     DataGridView dgvGridView = stcList.SelectedTab == stiTabWord ? dgvWord : dgvEvent; 
     int idType = stcList.SelectedTab == stiTabWord ? 1 : 2; 
     FillDataGrid(idType, word, dgvGridView); 
    } 

    if (_tmrDelaySearch != null) 
    _tmrDelaySearch.Stop(); 
} 
Verwandte Themen