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

时间:2010-06-01 01:51:19

标签: c# wpf visual-studio user-interface

我有一个在用户在搜索框中输入时调用的函数。在实际执行函数之前,我想等待用户完成输入。我知道如何在JavaScript中通过超时轻松完成此任务,但我如何在C#中执行相同的操作?另外,在我假设用户输入完成之前,我应该等多久? 100ms的?

6 个答案:

答案 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