如果用户选择.NET 2.0 ListView中的所有项目,ListView将为每个项目触发SelectedIndexChanged事件,而不是触发事件以指示选择已更改.
如果用户然后单击以选择列表中的一个项目,则ListView将为未选中的每个项目触发SelectedIndexChanged事件,然后为单个新选择的项目触发SelectedIndexChanged事件,而不是触发事件以指示选择已经改变.
如果您在SelectedIndexChanged事件处理程序中有代码,当您开始在列表中有几百/千个项目时,程序将变得非常无响应.
我考虑过停留计时器等.
但有没有人有一个很好的解决方案,以避免成千上万的不必要的ListView.SelectedIndexChange事件,什么时候真的会有一个事件呢?
伊恩的好解决方案.我把它拿到了可重复使用的类中,确保正确处理定时器.我还减少了间隔,以获得更具响应性的应用程序.此控件还可以双重缓冲以减少闪烁.
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()); } }
如果可以改进,请告诉我.