当用户停止输入时如何处理TextChanged事件?

10

我有一个带有已连接TextChanged事件的 TextBox。最终,它将向SQL数据库发出查询,因此我想限制查询的数量。

我只想在用户没有按键大约300毫秒左右时才进行查询。如果由于某些原因先前的查询仍在执行,我需要取消该查询,然后发出新的查询。

5个回答

9
创建一个 System.Windows.Forms.Timer 并在每次按键后重置它(例如停止,然后启动它)。如果定时器事件被触发,则禁用定时器。

这是我使用的方法,它完美地运行了。令人惊讶的是,我没有收到任何关于UI被另一个线程更新的异常? - esac
短回答是事件在UI线程中执行。这很有道理,考虑到它在System.Windows.Forms命名空间中。请参阅http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S1。 - Brian

1
使用响应式框架来触发一系列事件。我不确定这会如何工作,但您可以在此处阅读相关信息(.NET的响应式扩展),看看它是否能够满足您的需求。这里还有许多示例:示例。"节流"示例可能是您要找的内容。

0
感谢 @Brian 的想法和 这个答案,我自己也想到了使用计时器来处理这个问题的方法。这对我很有效。希望它也能帮助其他人:
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();
}

0

添加第二个ActionListener,每当用户按下任意键时调用它,并在调用时将当前时间保存到全局变量中。然后,当TextChanged事件被调用时,检查全局变量与当前时间之间的时间差。

如果时间差小于300毫秒,则启动一个计时器,在300毫秒后执行查询。如果用户按下另一个键,首先重置计时器。


这需要用户等待300毫秒,然后键入另一个字符才能提交结果。 - Brian

0

1)创建一个计时器。

2)为计时器的Tick事件创建一个处理程序。在每个tick上检查是否已经过了足够的空闲时间,如果是,则停止计时器并执行查询。

3)每当文本框上发生键盘按键事件时,重新启动计时器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接