2010-06-24 99 views
8

我有一個TextBoxTextChanged事件連線。最後,它正在查詢SQL數據庫,所以我想限制查詢的數量。僅當用戶停止輸入時如何處理TextChanged事件?

我只想做出查詢如果用戶沒有按下一個鍵說300毫秒左右。如果由於某種原因前一個查詢仍在執行,我需要取消它,然後發出一個新的查詢。

回答

8

創建一個System.Windows.Forms.Timer並在每次按鍵後重置(例如停止然後啓動它)。如果定時器事件被觸發,則禁用定時器。

+0

這是我使用的方法,它完美地工作。令人驚訝的是,我沒有得到關於另一個線程正在更新的UI的例外情況? – esac 2010-06-24 18:40:01

+0

請參閱http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S1。簡短的回答是,該事件在UI線程中執行。考慮到它在'System.Windows.Forms'命名空間中,這是有道理的。 – Brian 2010-06-24 18:43:56

+0

請注意,上面的MSDN雜誌鏈接不再是直接鏈接。您仍然可以通過[archive.org]訪問它(https://web.archive.org/web/20130219050936/http://msdn.microsoft.com/en-us/magazine/cc164015.aspx)。或者,從該頁面下載2004年2月的雜誌。如果您沒有CHM閱讀器,可以通過使用7zip提取CHM文件並打開'/ MSDNMagazineFebruary2004en-us/TimersinNET/chm.htm'來訪問文章 – Brian 2017-09-15 18:34:57

0

添加第二個actionlistener,只要用戶按下任意鍵並被調用,就會將當前時間保存到全局變量中。然後,當您的TextChanged事件被調用時,它會檢查全局變量與當前時間之間的時間差異。

如果差值小於300毫秒,則啓動計時器以在300毫秒後執行查詢。然後,如果用戶按下另一個鍵,則首先重設定時器。

+0

這需要用戶等待300毫秒,然後如果他們想要提交結果,請鍵入另一個字符。 – Brian 2010-06-24 18:10:08

1

使用Reactive Framework來觸發一系列事件。我不確定究竟是這是如何工作的,但你可以在這裏閱讀(Reactive Extensions for .NET),看它是否能滿足你的需求。這裏也有一些例子:Examples。 「Throttling」示例可能是您要查找的內容。

0

1)創建一個計時器。

2)爲您的計時器的Tick事件創建一個處理程序。在每個記號上,檢查是否有足夠的空閒時間,如果有,則停止定時器並執行查詢。

3)每當在該文本框上發生按鍵時,重新啓動定時器。

1

感謝@ Brian的想法和this answer,我想出了自己使用定時器來處理這個問題的版本。這對我來說工作得很好。我希望它可以幫助其他人:

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(); 
}