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

C# WinForm MDI父窗体向子窗体传值的实现方法

问题根因

现有代码存在4个核心问题导致传值失败:

  • 子窗体只定义了接收1个字符串参数的构造函数,菜单唤起时调用的无参new Child()找不到匹配构造,无法正常编译
  • ON按钮点击事件中虽然创建了带设备名的子窗体实例,但既没有设置MdiParent、也没有调用Show()方法,这个实例根本不会在MDI容器中展示
  • 两种唤起逻辑完全独立:如果子窗体已经通过菜单打开,点击ON按钮时新创建的子窗体实例和已打开的实例不是同一个,数据无法同步到已展示的窗体上
  • 子窗体构造函数只预留了设备名1个参数的接收通道,设备型号、生产日期两个字段没有传值入口,且代码存在变量拼写错误、语句缺分号的语法问题

修正实现

第一步:改造子窗体代码

保留无参构造兼容菜单唤起场景,新增公开的设备信息更新方法,同时支持初始化传值和已打开窗体的实时数据更新,避免重复创建实例:

public partial class Child : Form
{
    // 无参构造,供菜单唤起场景使用
    public Child()
    {
        InitializeComponent();
    }

    /// <summary>
    /// 加载/更新设备展示信息
    /// </summary>
    /// <param name="deviceName">设备名称</param>
    /// <param name="deviceModel">设备型号</param>
    /// <param name="manufactureDate">生产日期</param>
    public void UpdateDeviceDisplay(string deviceName, string deviceModel, string manufactureDate)
    {
        name_lbl.Text = deviceName;
        model_lbl.Text = deviceModel;
        date_lbl.Text = manufactureDate;
    }
}

第二步:修正父窗体全局定义与ON按钮逻辑

先把三个设备信息定义为父窗体全局变量方便复用,点击ON按钮时优先复用已打开的子窗体实例,不存在再新建,统一传值:

// 父窗体全局设备信息字段
private string deviceName;
private string deviceModel;
private string manuFacturedDate;

private void btnOn_Click(object sender, EventArgs e)
{
    // 赋值设备信息
    deviceName = "Notebook520220624";
    deviceModel =  "520220627";
    manuFacturedDate = "220627";

    Child targetForm = null;
    // 检查子窗体是否已打开
    if (Application.OpenForms["Child"] is Child openedForm)
    {
        targetForm = openedForm;
    }
    else
    {
        // 子窗体未打开则新建实例
        targetForm = new Child();
        targetForm.MdiParent = this;
        targetForm.Show();
    }
    // 新、旧实例统一调用方法更新展示数据
    targetForm.UpdateDeviceDisplay(deviceName, deviceModel, manuFacturedDate);
    targetForm.Focus();
}

第三步:修正父窗体菜单唤起逻辑

保持原有单实例判断逻辑,可按需选择是否在菜单唤起时自动加载已存储的设备信息:

private void DeviceInfomationToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (Application.OpenForms["Child"] is Child deviceInfo)
    {
        deviceInfo.Focus();
        // 需要菜单唤起时自动加载已存设备信息就放开下方注释
        // if (!string.IsNullOrEmpty(deviceName))
        // {
        //     deviceInfo.UpdateDeviceDisplay(deviceName, deviceModel, manuFacturedDate);
        // }
        return;
    }
    deviceInfo = new Child();
    deviceInfo.MdiParent = this;
    // 需要新建子窗体时自动带上已存设备信息就放开下方注释
    // if (!string.IsNullOrEmpty(deviceName))
    // {
    //     deviceInfo.UpdateDeviceDisplay(deviceName, deviceModel, manuFacturedDate);
    // }
    deviceInfo.Show();
}

注意事项
  • 必须把子窗体的Name属性设置为Child,否则Application.OpenForms["Child"]无法匹配到已打开的实例,会出现重复创建窗体的问题
  • 这种公开方法传值的方式比重载构造函数更适配MDI场景,不管窗体是已经初始化展示、还是未创建,都能随时同步数据,不需要维护多套构造逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:54:22