在c#中处理listview上的滚动事件

我有一个listview,使用backgroundworker生成缩略图。 当滚动列表视图时,我想暂停背景工作并获得滚动区域的当前值,当用户停止滚动列表视图时,根据滚动区域的值从项目开始恢复背景工作。

是否可以处理列表视图的滚动事件? 如果有,怎么样? 如果不是那么根据我上面描述的内容,什么是一个好的选择呢?

您必须添加对ListView类的支持,以便您可以收到有关滚动事件的通知。 在项目中添加一个新类并粘贴下面的代码。 编译。 将新的listview控件从工具箱顶部拖放到表单上。 为新的Scroll事件实现处理程序。

using System; using System.Windows.Forms; class MyListView : ListView { public event ScrollEventHandler Scroll; protected virtual void OnScroll(ScrollEventArgs e) { ScrollEventHandler handler = this.Scroll; if (handler != null) handler(this, e); } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 0x115) { // Trap WM_VSCROLL OnScroll(new ScrollEventArgs((ScrollEventType)(m.WParam.ToInt32() & 0xffff), 0)); } } } 

请注意滚动位置(ScrollEventArgs.NewValue)没有意义,它取决于ListView中的项目数。 我强制它为0.根据您的要求,您希望查看ScrollEventType.EndScroll通知以了解用户何时停止滚动。 其他任何东西都可以帮助您检测用户是否开始滚动。 例如:

 ScrollEventType mLastScroll = ScrollEventType.EndScroll; private void myListView1_Scroll(object sender, ScrollEventArgs e) { if (e.Type == ScrollEventType.EndScroll) scrollEnded(); else if (mLastScroll == ScrollEventType.EndScroll) scrollStarted(); mLastScroll = e.Type; } 

查看此postListView Scroll Event

使用本机窗口类侦听列表框上的滚动消息。 将适用于任何控制。

现在可以在.net 4中轻松完成滚动事件。

从ListView(m_ListView)中捕获Loaded事件并执行以下操作:

  if (VisualTreeHelper.GetChildrenCount(m_ListView) != 0) { Decorator border = VisualTreeHelper.GetChild(m_ListView, 0) as Decorator; ScrollViewer sv = border.Child as ScrollViewer; sv.ScrollChanged += ScrollViewer_ScrollChanged; } 

然后,实现您的ScrollViewer_ScrollChanged函数:

  private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { ... } 

根据@Adriaan Stander发布的关于提高滚动事件的课程的post如下。

 internal class ControlScrollListener : NativeWindow, IDisposable { public event ControlScrolledEventHandler ControlScrolled; public delegate void ControlScrolledEventHandler(object sender, EventArgs e); private const uint WM_HSCROLL = 0x114; private const uint WM_VSCROLL = 0x115; private readonly Control _control; public ControlScrollListener(Control control) { _control = control; AssignHandle(control.Handle); } protected bool Disposed { get; set; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (Disposed) return; if (disposing) { // Free other managed objects that implement IDisposable only } // release any unmanaged objects // set the object references to null ReleaseHandle(); Disposed = true; } protected override void WndProc(ref Message m) { HandleControlScrollMessages(m); base.WndProc(ref m); } private void HandleControlScrollMessages(Message m) { if (m.Msg == WM_HSCROLL | m.Msg == WM_VSCROLL) { if (ControlScrolled != null) { ControlScrolled(_control, new EventArgs()); } } } } 

像这样使用它……

声明一个字段:

  private ControlScrollListener _processListViewScrollListener; 

使用您需要知道的滚动控件进行实例化:

 _processListViewScrollListener = new ControlScrollListener(ProcessesListView); 

处理程序中的连线:

 _processListViewScrollListener.ControlScrolled += ProcessListViewScrollListener_ControlScrolled; 

处理事件:

 void ProcessListViewScrollListener_ControlScrolled(object sender, EventArgs e) { // do what you need to do } 

可以调整所引发事件中的事件args以包含更多有用的信息。 我只需要知道我的控件已经滚动了!