2012-01-09 20 views

答えて

1

特にTopItemプロパティのイベントはありません。しかし、以前のTopItemの結果をキャッシュして、項目の並べ替えの指標である他のイベント(例えば、PaintDrawItem)と比較することで、同じ効果を得ることができます。

private void WatchTopItemChanged(ListView listView, Action callOnChanged) { 
    var lastTopItem = listView.TopItem; 
    listView.DrawItem += delegate { 
    if (lastTopItem != listView.TopItem) { 
     lastTopItem = listView.TopItem; 
     callOnChanged(); 
    } 
    }; 
} 
2

TopItemが変更された可能性があることを検出するには、Scrollイベントが必要です。 ListViewには1つもありません。おそらく意図的なものですが、このクラスにはネイティブのWindowsコントロールのバグやスクロールを使用するハックを回避するいくつかのハッキングが含まれています。

これらのハッキングは、TopItemの変更のみを探すため、大したことではありません。 WndProc()メソッドをオーバーライドして、LVN_ENDSCROLLメッセージを取得できるようにします。これはうまくいきましたが、私はそれを完全にテストしませんでした。プロジェクトに新しいクラスを追加し、下にコードを貼り付けます。コンパイル。新しいコントロールをツールボックスの上部からフォームにドロップします。 TopItemChangedイベントを実装します。

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class MyListView : ListView { 
    public event EventHandler TopItemChanged; 

    protected virtual void OnTopItemChanged(EventArgs e) { 
     var handler = TopItemChanged; 
     if (handler != null) handler(this, e); 
    } 

    protected override void WndProc(ref Message m) { 
     // Trap LVN_ENDSCROLL, delivered with a WM_REFLECT + WM_NOTIFY message 
     if (m.Msg == 0x204e) { 
      var notify = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR)); 
      if (notify.code == -181 && !this.TopItem.Equals(lastTopItem)) { 
       OnTopItemChanged(EventArgs.Empty); 
       lastTopItem = this.TopItem; 
      } 
     } 
     base.WndProc(ref m); 
    } 

    private ListViewItem lastTopItem = null; 
    private struct NMHDR { 
     public IntPtr hwndFrom; 
     public IntPtr idFrom; 
     public int code; 
    } 
} 
関連する問題