You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# MDI项目:如何按子窗体当前显示顺序遍历子窗体?

按MDI子窗体当前显示顺序遍历的解决方案

我懂你遇到的这个问题——MDI父窗体自带的MdiChildren属性是按子窗体的创建顺序返回的,不管你怎么切换窗口的显示层级,这个顺序都不会跟着变。要按当前的显示Z顺序(也就是最上层/最下层的先后顺序)遍历子窗体,我们可以借助Win32 API来获取系统维护的真实窗口层级顺序。

步骤1:导入Win32 API函数

首先在你的父窗体(Form1)中添加以下代码,用来调用系统API获取窗口的Z顺序:

using System.Runtime.InteropServices;
using System.Collections.Generic;

// 导入获取窗口句柄的系统API
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

// 定义API需要的常量
private const uint GW_HWNDFIRST = 0;
private const uint GW_HWNDNEXT = 1;

步骤2:编写获取Z顺序子窗体的方法

接下来写一个方法,用来按当前显示顺序收集所有MDI子窗体:

private List<Form> GetMdiChildrenInZOrder()
{
    List<Form> orderedForms = new List<Form>();
    // 从当前MDI父窗体的第一个子窗口(最顶层)开始遍历
    IntPtr currentWnd = GetWindow(this.Handle, GW_HWNDFIRST);

    while (currentWnd != IntPtr.Zero)
    {
        // 将窗口句柄转换为Form对象
        Form childForm = Control.FromHandle(currentWnd) as Form;
        // 确认是当前父窗体的MDI子窗体
        if (childForm != null && childForm.MdiParent == this)
        {
            orderedForms.Add(childForm);
        }
        // 获取下一个层级的窗口
        currentWnd = GetWindow(currentWnd, GW_HWNDNEXT);
    }

    return orderedForms;
}

这个方法默认会从最顶层的子窗体开始,依次收集到最底层的子窗体。如果你需要反过来(从最底层到最顶层),可以把GW_HWNDFIRST换成GW_HWNDLAST,GW_HWNDNEXT换成GW_HWNDPREV即可。

步骤3:使用方法遍历子窗体

现在你可以用这个方法来按当前显示顺序遍历子窗体了,比如:

// 遍历按Z顺序排列的子窗体
foreach (Form child in GetMdiChildrenInZOrder())
{
    // 这里写你的处理逻辑,比如输出窗体标题
    Console.WriteLine($"当前显示顺序的窗体:{child.Text}");
}

原理说明

Windows系统会维护一个窗口Z顺序的层级列表,GetWindow函数可以按照这个层级逐个获取窗口句柄。我们通过筛选出属于当前MDI父窗体的子窗体,就能得到真实的显示顺序列表,而不是固定的创建顺序。

内容的提问来源于stack exchange,提问作者Manuel Paz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:36:51