我有一个winform应用程序,在主窗体上放置了一个文本框。
我想要的是,在 OnTextChanged 事件中,我需要查询sql(存储过程)表,以便为带有输入字符的匹配项列表。例如,如果我输入字母A然后自动我应该去数据库中搜索以字母“ A ”开头的名字,如果我输入字母“ L ”那么我应该去搜索以“ AL ”开头的名字等等。
问题是,如果我用户输入快,那么它应该取消正在进行的任何异步进程,并且只保留输入的最后一个字母的任务。
有关如何实现这些的任何线索?
答案 0 :(得分:2)
问题是,如果用户输入的速度很快,那么它应该取消任何异步过程 它不应该取消任何东西 - 除非你认为用户已经停止输入,否则不要开始任何事情。
我写了一些类似的东西,当用户输入我有一个线程启动一个新方法时,该方法在执行前等待(可配置)时间。另一次击键会再次调用该方法并重置等待时间 - 如果某人继续输入任务将无法执行;一旦它们停止它就会(例如在暂停200毫秒后)。
如果我是你,我会实现类似的东西,因为它避免了你不必去的时候去
更新 - 通过一个简单的例子,一个带有新表单和默认文本框的新项目应该允许以下代码满足您的需求(作为一个非常简单的起点)
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());
}
}