ToolStripTextBox 延迟 TextChanged

ToolStripTextBox delay TextChanged

我需要延迟检索 ToolStripTextBoxTextChanged 事件,以便在停止按键 x 秒后做一些事情..

我为 TextBox.

找到了这个(并且有效)示例

https://www.codeproject.com/Articles/20068/Custom-TextBox-that-Delays-the-TextChanged-Event

我试图将其转换为 ToolStripTextBox,但出现此错误:

void DelayTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    // stop timer.
    DelayTimer.Enabled = false;

    // set timer elapsed to true, so the OnTextChange knows to fire
    TimerElapsed = true;

    try
    {
        // use invoke to get back on the UI thread.
        this.Invoke(new DelayOverHandler(DelayOver), null);
    }
    catch { }
}

'DelayToolStripTextBox' does not contain a definition for 'Invoke' and no extension method 'Invoke' accepting a first argument of type 'DelayToolStripTextBox' could be found (are you missing a using directive or an assembly reference?)

ToolStripTextBox 没有“Invoke”方法..

有人能帮帮我吗?

提前致谢

为什么要使用一些外部代码?计时器可以轻松完成您的工作:

定义一个Timer,将在TextChange时启动。如果 Timer 是 运行,则应重新设置。 如果达到 Timer.Intervall,我们知道我们没有得到新的输入,因为定时器没有被重置。 现在 Timer 应该会触发它的 Tick 事件。该事件应该触发我们的方法,我们用 t.Tick += ClearText;.

绑定到它
// your trigger
private void textBox1_TextChanged(object sender, EventArgs e)
{
    StartEventAfterXSeconds();
}

private Timer t;

// your time-management
private void StartEventAfterXSeconds(int seconds = 10)
{
    if (t != null)
    {
        t.Stop();
    }
    else
    {
        t = new Timer();
        t.Tick += ClearText;
    }

    t.Interval = 1000 * seconds;
    t.Start();
}

// You action
public void ClearText(object sender, EventArgs args)
{
    this.textBox1.Text = null;
    t.Stop();
}

如果您想使用多个这些文本框,您应该将所有内容移动到 class。

  1. 继承文本框
  2. 添加应在延迟 后触发的事件。
  3. 构建一个启动计时器并由正常 TextChanged-event
  4. 触发的方法
  5. 实施触发新事件并停止计时器的 Tick-Method。

一些关于不带定时器的自定义事件的信息:simple custom event

public class TextBoxWithDelay : TextBox
{
    public TextBoxWithDelay()
    {
        this.DelayInSeconds = 10;

        this.TextChanged += OnTextChangedWaitForDelay;
    }

    public int DelayInSeconds { get; set; }
    public event EventHandler TextChangedWaitForDelay;

    private Timer t;
    private void OnTextChangedWaitForDelay(object sender, EventArgs args)
    {
        if (t != null)
        {
            t.Stop();
        }
        else
        {
            t = new Timer();
            t.Tick += DoIt;
        }

        t.Interval = 1000 * DelayInSeconds;
        t.Start();
    }

    public void DoIt(object sender, EventArgs args)
    {
        if (TextChangedWaitForDelay != null)
        {
            TextChangedWaitForDelay.Invoke(sender, args);
            t.Stop();
        }

    }
}

我也在寻找与您的情况类似的解决方案。我知道如何使用 setTimeout(去抖动)在 Javascript 中执行此操作,因此我开始通过任务在 C# 中执行类似的操作。这是我想出的:

private Dictionary<string, CancellationTokenSource> DebounceActions = new Dictionary<string, CancellationTokenSource>();

private void Debounce(string key, int millisecondsDelay, Action action)
{
    if (DebounceActions.ContainsKey(key))
    {
        DebounceActions[key].Cancel();
    }
    DebounceActions[key] = new CancellationTokenSource();
    var token = DebounceActions[key].Token;
    Task.Delay(millisecondsDelay, token).ContinueWith((task) =>
    {
        if (token.IsCancellationRequested)
        {
            token.ThrowIfCancellationRequested();
        }
        else
        {
            action();
        }
    }, token);
}

只要给它传递一个唯一的 key 来识别它从哪个方法调用。