2009-12-05 4 views
12

バックグラウンドワーカーを使用してサムネイルを生成するリストビューがあります。リストビューがスクロールされているとき、私はバックグラウンドワーカーを一時停止し、スクロール領域の現在の値を取得したいと考えています。ユーザーがリストビューをスクロールしなくても、スクロール領域の値に従って項目から開始します。リストビューのスクロールイベントをC言語で処理する#

リストビューのスクロールイベントを処理することはできますか?もしそうなら、どのように?もしそうでなければ、私は上に述べたことによると良い選択肢は何ですか?

答えて

16

スクロールイベントについて通知できるように、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)は意味がないことに注意してください。私はそれを0に強制しました。あなたの要件に従って、ユーザーがいつスクロールを止めたかを知るためのScrollEventType.EndScroll通知を監視する必要があります。他のものは、ユーザーがスクロールを開始したことを検出するのに役立ちます。たとえば、次のように簡単にあなたのリストビュー(m_ListView)から.NETで4

キャッチLoadedイベントを行われ、スクロールイベントをキャッチ

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

+3

WM_VSCROLLメッセージの制限事項については、http://stackoverflow.com/questions/1176703/listview-onscroll-event/1182232#1182232を参照してください。 – Grammarian

+0

この回答はネットフレームワーク2.0の厄介なバグを解決しました – Mandrake

1

がこの投稿をListView Scroll Event

が リストボックスのスクロールメッセージについて を聞くためにネイティブウィンドウクラスを使用して参照してください。任意のコントロールで動作します。

+0

@Adriaan Standerがスクロールイベントを発生させるためのクラスを投稿した投稿に基づいています。 http://stackoverflow.com/a/35645892/254215 – Dib

0

と、この操作を行います。その後、

 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

0

@Adriaan Stander poste dスクロールイベントを発生させるためのクラスは以下の通りです。で

_processListViewScrollListener = new ControlScrollListener(ProcessesListView); 

ワイヤー:

private ControlScrollListener _processListViewScrollListener; 

あなたはissrollingを知るために必要なコントロールとそれをインスタンス化:

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.ControlScrolled += ProcessListViewScrollListener_ControlScrolled; 

ハンドライベント:

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

上げイベントでのイベント引数は、より多くの有用な情報を含むように微調整することができます。私はコントロールがスクロールされたことを知る必要がありました!

+0

マウスホイールのスクロールは処理されません。スクロールバーを使用する必要があります。必要なら 'private const uint WM_MOUSEWHEEL = 0x020A;'を追加する必要があります。 – rism

関連する問題