1

我刚刚编写了我的第一个程序,该程序使用用户写入文本框中的信息来查询 SQL 数据库。这是使用 Windows 窗体的 C#。我的目标是让它类似于我们的 ERP 软件中的搜索功能,其中结果显示为用户类型(类似于 Google 的预测搜索功能)。

我正在努力减少对数据库的查询数量。现在我有它,以便在用户输入至少 3 个字符之前不会执行查询,否则会返回太多结果。

private void SearchField_TextChanged(object sender, EventArgs e)
{
    string search = SearchField.Text;
    if (search.Length >= 3)
    {
        dataGridView1.DataSource = sql.ExecuteQuery(Query(search));
    }
}

我要添加的是查询延迟,直到用户停止输入或者在这么多毫秒内没有输入字符。我一直在查看计时器类,但在努力解决我发现正确实现它的示例。基本上我想将我的代码更改为如下所示:

private void SearchField_TextChanged(object sender, EventArgs e)
{
    string search = SearchField.Text;
    if (search.Length >= 3 && aTimer.Time > 500)  //500 is milliseconds
    {
        dataGridView1.DataSource = sql.ExecuteQuery(Query(search));
    }
    aTimer.Reset();
}

如果使用计时器类,我不知道如何正确实现它。如果有更好的解决方案,我也会对此持开放态度。

4

1 回答 1

3

您要做的是将查询安排在将来的某个时间点发生,同时能够在用户键入时重置或撤销待处理的查询。这是一个例子:

using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    Timer queryTimer;
    TextBox SearchField;

    public Form1()
    {
        Controls.Add((SearchField = new TextBox { Location = new Point(10, 10) }));
        SearchField.TextChanged += new EventHandler(SearchField_TextChanged);
    }

    void SearchField_TextChanged(object sender, EventArgs e)
    {
        if (SearchField.Text.Length < 3)
            RevokeQueryTimer();
        else
            RestartQueryTimer();
    }

    void RevokeQueryTimer()
    {
        if (queryTimer != null)
        {
            queryTimer.Stop();
            queryTimer.Tick -= queryTimer_Tick;
            queryTimer = null;
        }
    }

    void RestartQueryTimer()
    {
        // Start or reset a pending query
        if (queryTimer == null)
        {
            queryTimer = new Timer { Enabled = true, Interval = 500 };
            queryTimer.Tick += queryTimer_Tick;
        }
        else
        {
            queryTimer.Stop();
            queryTimer.Start();
        }
    }

    void queryTimer_Tick(object sender, EventArgs e)
    {
        // Stop the timer so it doesn't fire again unless rescheduled
        RevokeQueryTimer();

        // Perform the query
        Trace.WriteLine(String.Format("Performing query on text \"{0}\"", SearchField.Text));
    }
}
于 2013-03-14T17:52:34.640 回答