当win表单的listview首项属性更改时,是否有任何事件触发?
答案 0 :(得分: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;
}
}
答案 1 :(得分:1)
TopItem
属性没有专门的事件。但是,您应该能够通过缓存上一个TopItem
结果并将其与其他事件进行比较来获得相同的效果,这些事件是项目重新排序的指标:例如Paint
和DrawItem
。
private void WatchTopItemChanged(ListView listView, Action callOnChanged) {
var lastTopItem = listView.TopItem;
listView.DrawItem += delegate {
if (lastTopItem != listView.TopItem) {
lastTopItem = listView.TopItem;
callOnChanged();
}
};
}