2012-01-09 44 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

您需要一個Scroll事件才能檢測到TopItem可能已經改變。 ListView沒有一個。這可能是故意的,該類包含一些解決本地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; 
    } 
}