【问题标题】:Stacking and delaying multiple UI change notifications堆叠和延迟多个 UI 更改通知
【发布时间】:2010-11-05 22:13:03
【问题描述】:

有人在代码中处理过这种情况吗?

用户正在输入区域(例如,富文本框)中输入内容。这会导致触发多个 TextChanged 事件。我们只想在用户停止输入时捕获最后更改的事件(即:5 秒内没有更改的事件)。

有没有人有一个干净的 C# sn-p 这样做?

【问题讨论】:

  • 我很想知道投反对票的原因。
  • 我不明白为什么这被否决了...
  • 您如何真正知道他们的用户何时停止输入?如果他们停止后有延迟,他们会再次开始输入以查看应用程序是否冻结(触发更多击键)?
  • 如果用户在 2 秒内(或任何预定义的时间间隔)没有输入,则可以认为用户已经停止输入了一段时间。目的是防止事件波通过 UI 传播(当这种处理成本很高时)
  • 哦,我完全明白了。只是很难预测用户接下来会做什么。我更喜欢尝试将界面塑造成数据,并提供一个可以减少我的工作(以及他们的困惑)的选择,例如,一个下拉列表而不是一个文本框(这是一个非常简单的例子;你d 可能必须为您的特定情况创建自己的 ui,但它可能比您现在所做的更好)。

标签: c# .net user-interface asynchronous


【解决方案1】:

创建一个间隔为五(或其他)秒的Timer,然后在您的TextChanged 事件中,停止计时器并重新启动它。然后,将您的处理程序代码移动到计时器的Tick 事件。

【讨论】:

  • +1。我只是输入相同的答案。我今天才这样做。我发现最好的延迟是500ms
  • 延迟时间取决于您在活动中所做的事情。
  • 是的,这也是我一直在考虑的设计。不幸的是 Timer 类绑定到 Windows.Forms (并且也为此进行了优化)。多 UI MVC 的一般准则是控制器不绑定到 UI 框架...
  • 使用 System.Timers.Timer 代替;它不受 WinForms 的约束。但请记住,它会在不同的线程上引发事件。
  • 或者,将计时器放在视图中(或者,将其与可重用组件中的文本框结合起来)并从计时器的 Tick 事件中调用控制器。
【解决方案2】:

好的,按照 SLaks 的建议使用 System.Threading.Timer 后,我得到了这个极其简单的 sn-p:

public sealed class CallBuffer : IDisposable
{

    private readonly TimeSpan _timeSpan;
    private readonly Timer _timer;

    public CallBuffer(Action call, TimeSpan timeSpan)
    {
        _timeSpan = timeSpan;
        _timer = new Timer(state => call());
    }

    public void Buffer()
    {
        _timer.Change(_timeSpan, TimeSpan.FromMilliseconds(-1));
    }

    void IDisposable.Dispose()
    {
        _timer.Dispose();
        GC.SuppressFinalize(this);
    }
}

我错过了什么吗?

请注意,它不关心 UI 线程(调用者应该通过适当的调用),这允许将此代码与视图分开。

【讨论】:

  • 由于你没有终结器,你不需要调用 GC.SuppressFinalize(this);在处置。另外,永远不要显式地实现 Dispose。
  • 另外,使用 System.Timers.Timer(不是 System.Threading.Timer)可能更容易;如果这样做,请调用 Stop(),然后在 Buffer() 中调用 Start()。
  • Slaks - 为什么不明确 IDisposable?
【解决方案3】:

我自己没用过,但this article 看起来很有希望。

我正在创建另一个控件,一个 准确地说是寻呼机控制,然后运行 成问题。问题是 例如,当用户输入时 100 导航到那个页面,我是 捕获 TextChanged 事件和它 将首先转到第 1 页,然后转到第 10,然后第 100 页(得到心理 图片)。我不希望这发生 有几个原因,但主要是 一个是因为我没有存储 内存中的每一页,它得到 选择页面时填充 从 SQL 服务器,所以我想 在需要时消除 3 个查询 对于前面提到的例子。

所以我决定不添加 我的寻呼机的“开始”或“刷新”按钮 控制,我会延迟文本框 TextChanged 事件只要 用户正在键入它不会触发 事件直到他/她完成(延迟 达到阈值)。

【讨论】:

    【解决方案4】:

    考虑使用Leave 事件,该事件应在用户跳出控件时触发。

    显然,这取决于控件正在做什么以及用户期望什么。

    【讨论】:

      猜你喜欢
      • 2012-06-04
      • 2013-10-03
      • 2013-06-11
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-28
      相关资源
      最近更新 更多