2009-12-05 104 views
12

我有一個使用backgroundworker生成縮略圖的listview。當列表視圖正在滾動時,我想暫停背景工作並獲取滾動區域的當前值,當用戶停止滾動列表視圖時,根據滾動區域的值從項目開始恢復背景工作。c處理listview中的scroll事件#

是否有可能處理列表視圖的滾動事件?如果是的話如何?如果不是,那麼根據我上面所描述的,什麼是一個好的選擇?

回答

16

您必須添加對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; 
} 
+0

非常感謝nobugz。這正是我想要實現的。 – murasaki5 2009-12-05 12:34:58

+3

閱讀http://stackoverflow.com/questions/1176703/listview-onscroll-event/1182232#1182232看到WM_VSCROLL消息的一些限制。 – Grammarian 2009-12-06 07:59:49

+0

這個答案已經解決了網格框架2.0與網格線上的一個討厭的bug – Mandrake 2011-05-27 17:52:51

1

看到這個職位ListView Scroll Event

使用原生窗口類聽 有關 列表框的滾動消息。將與任何控制工作。

+0

根據@Adriaan Stander發佈我的課程提出滾動事件的帖子如下。 http://stackoverflow.com/a/35645892/254215 – Dib 2016-02-26 07:27:03

0

捕獲滾動事件現在很容易在.NET做4

趕上Loaded事件從您的ListView(m_ListView),並做到這一點:

 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) 
    { 
     ... 
    } 
+1

這是針對WPF的。有用的信息,但問題是Windows窗體。 – flobadob 2014-11-07 16:05:59

0

根據@Adriaan Stander的職位d我的課程提出滾動事件在下面。

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

使用它是這樣的...

聲明一個字段:

_processListViewScrollListener = new ControlScrollListener(ProcessesListView); 

絲:

private ControlScrollListener _processListViewScrollListener; 

與您需要知道issrolling控件中實例化處理者:

_processListViewScrollListener.ControlScrolled += ProcessListViewScrollListener_ControlScrolled; 

處理函數的事件:

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

在引發事件的事件參數可以調整,以包含更多有用的信息。我只需要知道我的控制已經滾動!

+0

不處理鼠標滾輪。必須使用滾動條。如果你想要的話,需要添加'private const uint WM_MOUSEWHEEL = 0x020A;'。 – rism 2017-12-18 07:10:40