2

我有一个 winform 应用程序,并在主窗体上放置了一个文本框。

我想要的是在OnTextChanged事件中,我需要查询 sql(存储过程)表,以便提供与键入的字符匹配的列表。例如,如果我输入字母 A,那么我应该自动在数据库中搜索以字母“ A ”开头的名字,如果我然后输入字母“ L ”,那么我应该去搜索以“ AL ”开头的名字等等.

问题是,如果我用户输入速度很快,那么它应该取消任何正在进行的异步进程,并只保留最后一个输入字母的任务。

关于如何实现这些的任何线索?

4

1 回答 1

2

问题是,如果我用户输入速度很快,那么它应该取消任何异步进程 它不需要取消任何东西 - 诀窍是在你认为用户已经停止输入之前不要开始任何东西。

我写了一些类似的东西,当用户键入时,我让一个线程启动一个新方法,该方法在执行之前等待(可配置)时间。另一个击键将再次调用该方法并重置等待期——如果有人继续键入任务将不会执行则有效;一旦他们停止它就会(例如在 200 毫秒暂停后)。

如果我是你,我会实现类似的东西,因为它避免在你不需要的时候使用 SQL

更新 - 通过一个简单的例子,一个具有新表单和默认文本框的新项目应该允许以下代码满足您的需要(作为一个非常简单的起点)

 public partial class Form1 : Form
    {
        private bool _waiting;
        private bool _keyPressed;
        private const int TypingDelay = 220; // ms used for delay between keystrokes to initiate search

        public Form1()
        {
            InitializeComponent();
        }

        private void WaitWhileUserTyping()
        {
            var keepWaiting = true;

            while (keepWaiting)
            {
                _keyPressed = false;

                Thread.Sleep(TypingDelay);

                keepWaiting = _keyPressed;
            }

            Invoke((MethodInvoker)(ExecuteSearch));

            _waiting = false;
        }

        private void ExecuteSearch()
        {
            Thread.Sleep(200); // do lookup

            // show search results...
            MessageBox.Show("Search complete");
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

            if (_waiting)
            {
                _keyPressed = true;
                return;
            }

            _waiting = true;
            // kick off a thread to do the search if nothing happens after x ms
            ThreadPool.QueueUserWorkItem(_ => WaitWhileUserTyping());
        }
    }
于 2013-10-04T23:38:12.017 回答