如果用户正在键入,则延迟KeyUp操作(C#)

我有一个在用户在搜索框中输入时调用的函数。 我想在实际执行函数之前等待用户完成输入。 我知道如何在超时的JavaScript中轻松实现这一点,但我如何在C#中做同样的事情? 另外,在我假设用户输入完成之前,我应该等多久? 100ms的?

为所需的延迟间隔设置计时器。 在启动键事件上启动计时器。 如果计时器跳闸,则停止计时器并运行搜索。

100毫秒不是一个很好的间隔,但!! 即使输入完全均匀,这也是大约100wpm。

如果您对使用Reactive(Rx)框架感到满意,那么您可以非常快速地使用其内置限制来实现此function。

这是一篇关于这个主题的文章: Rx可以提高UI的响应能力

并且从文章中窃取和修改了一些代码:

var textObserver = (from text in Observable.FromEvent(_app.myTextField, "TextChanged") select text).Throttle(TimeSpan.FromSeconds(.5)); _searchObserver = textObserver.Subscribe(textChangedEvent => { var tb = (TextBox)textChangedEvent.Sender; DoMySearch(tb.Text); }); 

正如文章中所述(值得完整阅读),只要半秒钟过去而没有用户输入任何内容,就会触发lambda表达式中的代码。

我明天在我的开发PC面前清理这个例子,但这应该给你一个起点。

这是我基于Loren输入的工作代码:

 private void SearchTextBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) { if (SearchTextBoxTimer != null) { Console.WriteLine("The user is currently typing."); if (SearchTextBoxTimer.Interval < 750) { SearchTextBoxTimer.Interval += 750; Console.WriteLine("Delaying..."); } } else { Console.WriteLine("The user just started typing."); SearchTextBoxTimer = new System.Windows.Forms.Timer(); SearchTextBoxTimer.Tick += new EventHandler(SearchTextBoxTimer_Tick); SearchTextBoxTimer.Interval = 500; SearchTextBoxTimer.Start(); } } 

和事件处理程序:

 private void SearchTextBoxTimer_Tick(object sender, EventArgs e) { Console.WriteLine("The user finished typing."); if (SearchTextBox.Text == "") { ConsoleTextBox.Text = "Searching: All"; } else { ConsoleTextBox.Text = "Searching: " + SearchTextBox.Text; } SearchTextBox_TextChanged(); SearchTextBoxTimer.Stop(); SearchTextBoxTimer.Dispose(); SearchTextBoxTimer = null; } 

如果有人玩这个代码,请告诉我你是否调整了我输入的时间间隔。我认为它们还不是最优的。

一个建议是不要让用户感到惊讶。 这通常是一个很好的UI设计原则。 因此,只有在文本框失去焦点时才执行实际搜索。 将增量匹配的搜索字符串显示为用户类型(如Google)是一回事,而另一个则是在某些键盘延迟后通过未经请求的搜索让用户感到惊讶。 就个人而言,我会觉得这很烦人,因为我经常在进入时考虑搜索字符串。

这是一个解决此问题的代码示例

 using System; using System.Timers; using System.Windows.Input; using Timer = System.Timers.Timer; namespace Example { public partial class OnKeyUpInputExample { // Timer set to elapse after 750ms private Timer _timer = new Timer(750) { Enabled = false }; // Constructor public OnKeyUpInputExample() { //What to do when _timer elapses _timer.Elapsed += TextInput_OnKeyUpDone; } // Event handler private void TextInput_OnKeyUp(object sender, KeyEventArgs e) { // You could also put the .Stop() in an OnKeyDown event handler if you need to account for keys being held down _timer.Stop(); _timer.Start(); } // Function to complement timer elapse private void TextInput_OnKeyUpDone(object sender, ElapsedEventArgs e) { // If we don't stop the timer, it will keep elapsing on repeat. _timer.Stop(); this.Dispatcher.Invoke(() => { //Replace with code you want to run. Console.WriteLine("KeyUp timer elapsed"); }); } } } 

这里可以找到一些视图: 延迟函数调用

记录每个keyup事件的时间戳,并使用Timer类来延迟方法的执行。 在该方法中,您可以考虑用户是否已停止输入,将当前时间与上一个keyup事件时间戳进行比较。 您可以尝试间隔,确保响应。 限制命中也是明智的,并且只允许搜索至少3个字符。

计时器: http : //msdn.microsoft.com/en-us/library/system.threading.timer.aspx