当前位置:  开发笔记 > 编程语言 > 正文

如何避免成千上万不必要的ListView.SelectedIndexChanged事件?

如何解决《如何避免成千上万不必要的ListView.SelectedIndexChanged事件?》经验,为你挑选了1个好方法。

如果用户选择.NET 2.0 ListView中的所有项目,ListView将为每个项目触发SelectedIndexChanged事件,而不是触发事件以指示选择已更改.

如果用户然后单击以选择列表中的一个项目,则ListView将为未选中的每个项目触发SelectedIndexChanged事件,然后为单个新选择的项目触发SelectedIndexChanged事件,而不是触发事件以指示选择已经改变.

如果您在SelectedIndexChanged事件处理程序中有代码,当您开始在列表中有几百/千个项目时,程序将变得非常无响应.

我考虑过停留计时器等.

但有没有人有一个很好的解决方案,以避免成千上万的不必要的ListView.SelectedIndexChange事件,什么时候真的会有一个事件呢?



1> Robert Jeppe..:

伊恩的好解决方案.我把它拿到了可重复使用的类中,确保正确处理定时器.我还减少了间隔,以获得更具响应性的应用程序.此控件还可以双重缓冲以减少闪烁.

  public class DoublebufferedListView : System.Windows.Forms.ListView
  {
     private Timer m_changeDelayTimer = null;
     public DoublebufferedListView()
        : base()
     {
        // Set common properties for our listviews
        if (!SystemInformation.TerminalServerSession)
        {
           DoubleBuffered = true;
           SetStyle(ControlStyles.ResizeRedraw, true);
        }
     }

     /// 
     /// Make sure to properly dispose of the timer
     /// 
     /// 
     protected override void Dispose(bool disposing)
     {
        if (disposing && m_changeDelayTimer != null)
        {
           m_changeDelayTimer.Tick -= ChangeDelayTimerTick;
           m_changeDelayTimer.Dispose();
        }
        base.Dispose(disposing);
     }

     /// 
     /// Hack to avoid lots of unnecessary change events by marshaling with a timer:
     /// http://stackoverflow.com/questions/86793/how-to-avoid-thousands-of-needless-listview-selectedindexchanged-events
     /// 
     /// 
     protected override void OnSelectedIndexChanged(EventArgs e)
     {
        if (m_changeDelayTimer == null)
        {
           m_changeDelayTimer = new Timer();
           m_changeDelayTimer.Tick += ChangeDelayTimerTick;
           m_changeDelayTimer.Interval = 40;
        }
        // When a new SelectedIndexChanged event arrives, disable, then enable the
        // timer, effectively resetting it, so that after the last one in a batch
        // arrives, there is at least 40 ms before we react, plenty of time 
        // to wait any other selection events in the same batch.
        m_changeDelayTimer.Enabled = false;
        m_changeDelayTimer.Enabled = true;
     }

     private void ChangeDelayTimerTick(object sender, EventArgs e)
     {
        m_changeDelayTimer.Enabled = false;
        base.OnSelectedIndexChanged(new EventArgs());
     }
  }

如果可以改进,请告诉我.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有