首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >.NET - Textbox控件-等待用户完成键入

.NET - Textbox控件-等待用户完成键入
EN

Stack Overflow用户
提问于 2009-03-22 22:40:22
回答 5查看 18.6K关注 0票数 16

大家好,

有没有一种内置的方法可以知道用户何时完成了在文本框中的键入?(在按tab键或移动鼠标之前)我有一个数据库查询,该查询发生在textchanged事件上,一切都运行得很好。然而,我注意到当然有一点滞后,因为如果用户在文本框中快速输入,程序就会忙于查询每个字符。所以我希望的是一种查看用户是否已经完成输入的方法。因此,如果他们输入"a“并停止,则会触发一个事件。但是,如果他们输入"all the way“,事件会在y键之后触发。

我有一些想法在我的脑海中浮现,但我确信它们不是最有效的。比如测量自上一次textchange事件以来的时间,如果它大于某个值,那么它将继续运行我的其余过程。

让我知道你的想法。

语言: VB.NET框架:.Net 2.0

--编辑以澄清“完成键入”

EN

回答 5

Stack Overflow用户

发布于 2010-05-06 06:51:28

对于那些在.NET 2.0中需要类似东西的人,我在这里制作了一个派生自TextBox并使用相同方法的控件。希望这对你有所帮助

代码语言:javascript
复制
public partial class TextBox : System.Windows.Forms.TextBox
{

    private ManualResetEvent _delayMSE;
    public event EventHandler OnUserStopTyping;
    private delegate bool TestTimeout();

    public TextBox()
    {
        _delayMSE = new ManualResetEvent(false);
        this.TextChanged += new EventHandler(TextBox_TextChanged);
    }

    void TextBox_TextChanged(object sender, EventArgs e)
    {


        _delayMSE.Set();
        Thread.Sleep(20);
        _delayMSE.Reset();

        TestTimeout tester = new TestTimeout(TBDelay);
        tester.BeginInvoke(new AsyncCallback(Test), tester);

    }


    private void Test(IAsyncResult pResult)
    { 
        bool timedOut = (bool)((TestTimeout)pResult.AsyncState).EndInvoke(pResult);
        if (timedOut)
        {
            if (OnUserStopTyping != null)
                OnUserStopTyping(this, null);
        }
    }

    private bool TBDelay()
    { 
        return !_delayMSE.WaitOne(500, false); 
    }

}
票数 5
EN

Stack Overflow用户

发布于 2009-07-23 16:07:29

我最终尝试了Scott Weinstein answer,尽管它需要一些关于线程、委托和基本lambda语法的更深层次的知识。而且它工作得很好。他最初的回答并不是纯粹的复制-粘贴,所以我不得不做一些工作来让它工作。

我在Thread.Sleep中增加了很少的时间,因为我注意到,如果用户输入非常快,但在一些按键之间有很小的随机延迟,则invoke方法可能会发生两次。您还必须添加对WindowsBase程序集的引用才能使用Dispatcher。

我用1.5秒等待用户结束输入。

代码语言:javascript
复制
    // use manual reset event to Q up waiting threads.
    // each new text changed event clears the Q
    // only the last changed will hit the timeout, triggering the action
    private ManualResetEvent _delayMSE;
    private Func<bool> TBDelay;
    private delegate void ActionToRunWhenUserStopstyping();

    public Form1()
    {
        InitializeComponent();

        _delayMSE = new ManualResetEvent(false);
        TBDelay = () => !_delayMSE.WaitOne(1500, false);
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        _delayMSE.Set(); 

        // open the ResetEvent gate, to discard these delays    
        Thread.Sleep(20);
        // let all pending through the gate    
        _delayMSE.Reset();
        // close the gate
        TBDelay.BeginInvoke(res =>    
        {        
            // callback code        
            // check how we exited, via timeout or signal.        
            bool timedOut = TBDelay.EndInvoke(res);
            if (timedOut)
                Dispatcher.CurrentDispatcher.Invoke(
                    new ActionToRunWhenUserStopstyping(DoWhatEverYouNeed), 
                    DispatcherPriority.Input);
        }, null);
    }

    private void DoWhatEverYouNeed()
    {
        MessageBox.Show(textBox1.Text);
    }
票数 3
EN

Stack Overflow用户

发布于 2009-03-22 22:43:40

这取决于你所说的“完成输入”是什么意思。有一个事件可以让您知道用户何时离开了该特定控件的焦点。此外,还有一个changed even,它会在文本发生变化时告诉你。你可以做的是捕获两件事:

1)失去焦点

2)每次用户更改文本时,启动计时器,例如,20秒,如果用户在该时间内完成,则用户“完成”打字。也就是说,如果用户在该时间内没有做任何事情,那么就假设用户“完成”了。

如果这两件事中的任何一件发生,那么用户就完成了,请确保适当地停止并重新启动计时器。显然,您可以更改超时。

这完全取决于你想如何定义它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/671728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档