ListView似乎不支持Scroll事件。每当滚动列表时我都需要调用一个函数;我该怎么办呢?
答案 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
似乎对我来说很好,但您可能需要调整它以适合您的应用。
我希望这会有所帮助。