如何在ListView中监听滚动?

时间:2008-12-16 17:30:33

标签: c# winforms listview

ListView似乎不支持Scroll事件。每当滚动列表时我都需要调用一个函数;我该怎么办呢?

3 个答案:

答案 0 :(得分:6)

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

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

或者您可以覆盖列表视图并执行此操作:

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();
    }
}

答案 1 :(得分:4)

似乎最好的方法是布莱恩的解决方案。但是,它仅响应滚动条生成的事件,但不响应来自鼠标midbuttton的事件。

如果您更改条件:

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

由:

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

现在它在listview中的所有滚动事件中都会显示出来。

答案 2 :(得分:0)

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

我们依赖的事实是,当滚动ListView时,项目的位置会发生变化。如果我们检查第一个ListViewItem的{​​{1}}属性是否有变化,我们就可以跟踪是否发生了移动。

您需要将Bounds控件添加到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; } 的{​​{1}}事件添加处理程序:

Timer

100毫秒的默认Tick似乎对我来说很好,但您可能需要调整它以适合您的应用。

我希望这会有所帮助。