我有一个在用户在搜索框中输入时调用的函数。在实际执行函数之前,我想等待用户完成输入。我知道如何在JavaScript中通过超时轻松完成此任务,但我如何在C#中执行相同的操作?另外,在我假设用户输入完成之前,我应该等多久? 100ms的?
答案 0 :(得分:5)
如果您习惯使用Reactive(Rx)框架,那么您可以非常快速地使用其内置限制来实现此功能。
以下是关于此主题的文章:Rx Can Improve UI Responsiveness
一些代码被窃取&修改自文章:
var textObserver = (from text in Observable.FromEvent<TextChangedEventArgs>(_app.myTextField, "TextChanged")
select text).Throttle(TimeSpan.FromSeconds(.5));
_searchObserver = textObserver.Subscribe(textChangedEvent =>
{
var tb = (TextBox)textChangedEvent.Sender;
DoMySearch(tb.Text);
});
正如文章中所述(值得完整阅读),只要半秒钟过去而没有用户输入任何内容,就会触发lambda表达式中的代码。
明天,当我在我的开发PC前面时,我会清理这个例子,但这应该给你一个起点。
答案 1 :(得分:4)
这是我基于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;
}
如果有人玩这个代码,请告诉我你是否调整了我输入的时间间隔。我认为它们还不是最优的。
答案 2 :(得分:2)
为所需的延迟间隔设置计时器。在启动键事件上启动计时器。如果计时器跳闸,则停止计时器并运行搜索。
100ms是 NOT 一个好的间隔,但!!即使输入完全均匀,这也是大约100wpm。
答案 3 :(得分:0)
一个建议是不要让用户感到惊讶。这通常是一个很好的UI设计原则。因此,只有在文本框失去焦点时才执行实际搜索。显示增量匹配搜索字符串作为用户类型(如Google)是一回事,而另一个是在一些键盘延迟后通过未经请求的搜索让用户感到惊讶。就个人而言,我会觉得这很烦人,因为我经常在进入时考虑搜索字符串。
答案 4 :(得分:0)
这是解决此问题的代码示例
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");
});
}
}
}
答案 5 :(得分:-1)
有些观点可以在这里找到:Delayed function calls
记录每个keyup事件的时间戳,并使用Timer类来延迟方法的执行。在该方法中,您可以考虑用户是否已停止输入,将当前时间与上一个keyup事件时间戳进行比较。您可以尝试间隔,确保响应。限制命中也很聪明,只允许搜索至少3个字符。
计时器:http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx