ToolStripTextBox延迟TextChanged

时间:2018-02-01 09:00:25

标签: c# winforms .net-4.0

我需要延迟检索public ArrayList<GenericModel> getList(GenericModel model) { ValueEventListener postListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { ArrayList<GenericModel> genericModels = new ArrayList<>(); for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { GenericModel genericModel = postSnapshot.getValue(model.getClass()); genericModels.add(genericModel); } Collections.sort(genericModels, (o1, o2) -> o1.getDate().compareTo(o2.getDate())); return genericModels; } @Override public void onCancelled(DatabaseError databaseError) { return null; } }; mDatabase.child(model.getTableName()).child(mUser.getUid()).addListenerForSingleValueEvent(postListener); } 的{​​{1}}事件,在停止按键x秒后做一些事情。

我找到了TextChanged的这个(并且有效)示例。

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

我尝试将其转换为ToolStripTextBox,但我收到了此错误:

TextBox
  

'DelayToolStripTextBox'不包含'Invoke'的定义   没有扩展方法'Invoke'接受第一个类型的参数   可以找到'DelayToolStripTextBox'(你是否错过了使用   指令或程序集引用?)

ToolStripTextBox没有'Invoke`方法..

有人可以帮助我吗?

提前致谢

2 个答案:

答案 0 :(得分:2)

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

定义一个Timer,它将在TextChange时启动。如果Timer正在运行,则应该重置。 如果达到Timer.Intervall,我们就知道没有新的输入,因为没有重置timmer。 现在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();
}

如果你想使用多个这些TextBox,你应该把所有东西都移到一个类。

  1. 继承文本框
  2. 添加一个应在延迟后触发的事件。
  3. 构建一个启动计时器的方法,并由正常TextChanged - 事件
  4. 触发
  5. 实施Tick-Method,它会触发您的新事件并停止计时器。
  6. 有关自定义事件的一些信息,没有带有计时器的自定义事件: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();
            }
    
        }
    }
    

答案 1 :(得分:1)

我也在寻找类似于你情况的解决方案。我知道如何使用setTimeout(debounce)在Javascript中执行此操作,因此我开始在C#中通过Tasks执行类似的操作。这就是我想出的:

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即可识别它所拨打的方式。