C# 如何在ListView中侦听滚动?

C# 如何在ListView中侦听滚动?,c#,winforms,listview,C#,Winforms,Listview,ListView似乎不支持滚动事件。每当滚动列表时,我需要调用一个函数;我该怎么做呢?这里有一个解决方案,它考虑了列表视图的每个显示模式: 我们依赖于这样一个事实,即当滚动列表视图时,项目的位置会发生变化。如果我们检查第一个ListViewItem的Bounds属性中是否有更改,我们可以跟踪是否发生了移动 您需要将计时器控件添加到您的列表视图打开的同一窗体中,并将其已启用属性设置为真(这意味着它将定期启动,而无需启动)。还要向表单类中添加一个私有变量,以记录第一个项的边界 private Rec

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

这里有一个解决方案,它考虑了
列表视图的每个显示模式:

我们依赖于这样一个事实,即当滚动
列表视图时,项目的位置会发生变化。如果我们检查第一个
ListViewItem
Bounds
属性中是否有更改,我们可以跟踪是否发生了移动

您需要将
计时器
控件添加到您的
列表视图
打开的同一窗体中,并将其
已启用
属性设置为
(这意味着它将定期启动,而无需
启动
)。还要向表单类中添加一个私有变量,以记录第一个项的
边界

private Rectangle _firstItemBounds = null;
填充
列表视图
时,将此变量设置为第一项的
边界
。例如:

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;
}
默认的
计时器间隔
100ms对我来说似乎很好,但您可能需要调整它以适合您的应用程序


我希望这有帮助。

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

如果在滚动时更改项目,我建议将listview设置为virtual

或者您可以覆盖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();
    }
}

看来最好的方法是布莱恩的解决方案。但是,它只响应滚动条生成的事件,而不响应鼠标midbutton生成的事件

如果更改条件,请执行以下操作:

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

现在它在listview中响应所有滚动事件

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