2008-12-16 78 views

回答

6

为什么在列表滚动时需要调用函数?

如果您正在更改项目,因为它滚动我建议将列表视图设置为虚拟。

或者你可以重写ListView和做到这一点:

public class TestListView : System.Windows.Forms.ListView 
{ 
    private const int WM_HSCROLL = 0x114; 
    private const int WM_VSCROLL = 0x115; 
    public event EventHandler Scroll; 

    protected void OnScroll() 
    { 

     if (this.Scroll != null) 
      this.Scroll(this, EventArgs.Empty); 

    } 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     base.WndProc(ref m); 
     if (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL) 
      this.OnScroll(); 
    } 
} 
0

下面是尊重每个ListView的显示模式的解决方案:

我们依靠的事实,作为ListView滚动时,项目的位置变化。如果我们检查第一个ListViewItemBounds属性中的更改,我们可以跟踪是否发生了移动。

你需要一个Timer控件添加到同一形成你ListView并且它的Enabled属性设置为True(这意味着它会定期火而不必Start版)。还要添加一个私有变量到您的表单类来记录第一个项目的Bounds

private Rectangle _firstItemBounds = null; 

当填充您的ListView,这个变量设置为第一个项目的Bounds。例如:

private void Form1_Load(object sender, EventArgs e) 
{ 
    for (int i = 0; i < 1000; i++) 
    { 
     listView1.Items.Add(new ListViewItem("Item " + i)); 
    } 

    _firstItemBounds = listView1.Items[0].Bounds; 
} 

然后添加一个处理程序TimerTick事件:

private void timer1_Tick(object sender, EventArgs e) 
{ 
    if (listView1.Items[0] == null) 
    { 
     return; 
    } 

    Rectangle bounds = listView1.Items[0].Bounds; 

    if (bounds != _firstItemBounds) 
    { 
     _firstItemBounds = bounds; 

     // Any scroll logic here 
     // ... 
    } 
} 

默认为100ms的Timer Interval似乎为我工作得很好,但你可能需要调整,使之适合你的申请。

我希望这会有所帮助。

4

看来,最好的办法是布赖恩的解决方案。但是,它只响应由滚动条生成的事件,但不响应鼠标中键的事件。

如果更改条件

if (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL) 
      this.OnScroll(); 

由:

if (m.Msg == 0x000c2c9) 
      this.OnScroll(); 

现在respods在列表视图所有滚动事件。

相关问题