0

如何监视集合(接口:)的成员何时System.Collections.ICollection更改?我正在尝试将列的顺序保存在System.Windows.Forms.ListView.Columns.

我已经为public event ColumnReorderedEventHandler ColumnReordered;

this.MyListView.ColumnReordered += new System.Windows.Forms.ColumnReorderedEventHandler(ColumnReordered);

当我的班级被叫到时:

public void ColumnReordered(object sender, EventArgs e)
{
    ListView.ColumnHeaderCollection chc = sender as ListView.ColumnHeaderCollection;
    ColumnReorderedEvemtArgs crea = e as ColumnReorderedEventArgs;
    if ((chc == null) || (crea == null)) return;

    // Prints expected values.
    Console.WriteLine("{0} -> {1}", crea.OldDisplayIndex, crea.NewDisplayIndex);

    // Prints previous state; NOT current state.
    for (int k = 0; k < chc.Count; k++)
    {
        ColumnHeader columnHeader = chc[k] as ColumnHeader;
        if (columnHeader == null)
            break;

        Console.WriteLine("{0}", columnHeader.DisplayIndex);
    }
}

这让我相信这不是我想要保存状态的地方,因为更改尚未反映在返回的对象中 ( sender)。当用户操作它们时,如何立即保存列的顺序?

4

1 回答 1

0

我做了一些研究和一些测试。列表视图的列部分是一个名为SysHeader32的单独窗口句柄。

当列的顺序发生变化时,标头句柄会收到一条 HDM_SETORDERARRAY 消息:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb775369(v=vs.85).aspx

其中lParam包含一个指向数组的指针,该数组保存列的修改顺序。例如,当您有三列时,如果没有任何更改,数组将如下所示:

int[] indexes = { 0, 1, 2 };

当我切换前两列时,数组如下所示:

int[] indexes = { 1, 0, 2 };

然后,您可以使用存储在数组中的索引遍历数组以从列表视图控件中检索列。

因此,换句话说,您必须找到标头的句柄,然后设置一个WndProc来拦截传入的 windows 消息,然后检测是否收到了 HDM_SETORDERARRAY。如果是,请读取lParam的值。

您可以使用EnumChildWindows枚举/搜索句柄的子句柄:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633494(v=vs.85).aspx

要设置钩子,拦截报头句柄的消息,请参阅以下堆栈溢出问题:

如何拦截发送到窗口的消息?

请注意,当索引已经更新时,会收到 HDM_SETORDERARRAY。

于 2013-10-25T01:25:54.697 回答