连续输入时不要引发TextChanged [英] Don't raise TextChanged while continuous typing

查看:79
本文介绍了连续输入时不要引发TextChanged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文本框,其中有一个相当大的 _TextChanged 事件处理程序。在正常的键入条件下,性能还可以,但是当用户执行长时间的连续操作(例如按住退格按钮一次删除大量文本)时,它的性能会明显滞后。

I have a textbox that has a fairly hefty _TextChanged event handler. Under normal typing condition the performance is okay, but it can noticeably lag when the user performs a long continuous action, such as keeping the backspace button pressed to delete a lot of text at once.

例如,该事件完成了0.2秒,但用户每0.1秒执行一次删除。因此,它无法赶上进度,将需要处理大量积压的事件,从而导致UI滞后。

For example, the event took 0.2 seconds to complete, but the user is performing one deletion every 0.1 seconds. Thus, it cannot catch up and there will be a backlog of events that needs to be handled, leading to the UI lagging.

但是,该事件不需要运行对于这些中间状态,因为它只在乎最终结果。有什么办法让事件处理程序知道它应该只处理最新的事件,而忽略所有先前的过时更改?

However, the event does not need to run for these in-between states, because it only cares about the end result. Is there any way to let the event handler know that it should process only the latest event, and ignore all the previous stale changes?

推荐答案

根据经验,我已经多次遇到此问题,到目前为止,发现此解决方案简单而整洁。它可以在 Windows窗体中运行,但可以轻松转换为 WPF

I've come across this problem several times based on experience found this solution simple and neat so far. It is working in Windows Form but can easily be converted to WPF.

工作原理:

TypeAssistant 的对象被获取时通知发生了文本更改,它运行了一个计时器。在 WaitingMilliSeconds 之后,计时器引发 Idleی事件。通过处理此事件,您可以完成所需的任何工作。如果在从计时器启动开始的时间段内又发生了文本更改,此后又发生了 WaitingMilliSeconds ,则计时器重置。

When an object of TypeAssistant gets informed that a text change has happened, it runs a timer. After WaitingMilliSeconds the timer raises Idleی event. By handling this event you can do whatever job you desire. If another text change occurs in the time period starting from the timer start and WaitingMilliSeconds afterwards, the timer resets.

public class TypeAssistant
{
    public event EventHandler Idled = delegate { };
    public int WaitingMilliSeconds { get; set; }
    System.Threading.Timer waitingTimer;

    public TypeAssistant(int waitingMilliSeconds = 600)
    {
        WaitingMilliSeconds = waitingMilliSeconds;
        waitingTimer = new Timer(p =>
        {
            Idled(this, EventArgs.Empty);
        });
    }
    public void TextChanged()
    {
        waitingTimer.Change(WaitingMilliSeconds, System.Threading.Timeout.Infinite);
    }
}

用法:

public partial class Form1 : Form
{
    TypeAssistant assistant;
    public Form1()
    {
        InitializeComponent();
        assistant = new TypeAssistant();
        assistant.Idled += assistant_Idled;          
    }

    void assistant_Idled(object sender, EventArgs e)
    {
        this.Invoke(
        new MethodInvoker(() =>
        {
            // do your job here
        }));
    }

    private void yourFastReactingTextBox_TextChanged(object sender, EventArgs e)
    {
        assistant.TextChanged();
    }
}

优势:


  • 简单!

  • 同时在 WPF Windows Form
  • $ b中工作$ b
  • 使用.Net Framework 3.5 +

  • Simple!
  • Working both in WPF and Windows Form
  • Working with .Net Framework 3.5+

缺点:


  • 再运行一个线程

  • 需要调用,而不是直接操纵表单

这篇关于连续输入时不要引发TextChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆