【发布时间】:2012-01-09 16:54:20
【问题描述】:
当 win 表单的 listview 顶部项目属性更改时,是否会触发任何事件?
【问题讨论】:
当 win 表单的 listview 顶部项目属性更改时,是否会触发任何事件?
【问题讨论】:
您需要一个 Scroll 事件来检测 TopItem 可能已更改。 ListView 没有。这可能是故意的,该类包含一些解决本机 Windows 控件中的错误的 hack,即使用滚动的 hack。
但是,这些技巧在您的情况下应该无关紧要,因为您只在 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;
}
}
【讨论】:
没有专门针对 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();
}
};
}
【讨论】: