在 C# 程序中保存 UI 的状态

本文关键字:UI 状态 保存 程序 | 更新日期: 2023-09-27 18:36:56

如何监视集合(接口: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 ) 中。如何在用户操作列时立即保存列的顺序?

在 C# 程序中保存 UI 的状态

我做了一些研究和一些测试。列表视图的列部分是名为 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。