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

如何在Visual Studio窗体应用中跨窗体控制菜单的启用与禁用?

解决WinForms主窗体菜单随子窗体状态启用/禁用的问题

错误原因分析

你遇到的An object reference is required...错误,是因为直接通过类名TelaPrincipal.M_Selecao访问菜单控件——菜单是主窗体实例的成员,不是静态成员,必须通过主窗体的实际对象实例才能访问。另外,直接修改TelaPrincipal.Designer.cs里的控件访问修饰符不可取,因为设计器会自动覆盖该文件的内容,你的修改会丢失。

下面提供两种可靠的解决方案:


方案一:子窗体端处理(需传递主窗体实例)

1. 封装主窗体菜单控件

在TelaPrincipal.cs中添加一个公共属性,封装菜单控件,避免直接暴露控件且不会被设计器覆盖:

public System.Windows.Forms.ToolStripMenuItem SelecaoMenu
{
    get { return M_Selecao; }
}

2. 打开子窗体时传递主窗体实例

在主窗体打开Expenses子窗体的代码中,将当前主窗体实例设为子窗体的Owner:

private void AbrirExpensesToolStripMenuItem_Click(object sender, EventArgs e)
{
    ExpensesForm expensesForm = new ExpensesForm();
    // 传递主窗体实例给子窗体
    expensesForm.Owner = this;
    expensesForm.Show();
    // 子窗体打开时启用菜单
    M_Selecao.Enabled = true;
}

3. 子窗体关闭时禁用菜单

在Expenses子窗体的FormClosed事件中,通过Owner获取主窗体实例并操作菜单:

private void ExpensesForm_FormClosed(object sender, FormClosedEventArgs e)
{
    TelaPrincipal mainForm = this.Owner as TelaPrincipal;
    if (mainForm != null)
    {
        mainForm.SelecaoMenu.Enabled = false;
    }
}

方案二:主窗体端处理(推荐,解耦性更好)

这种方法不需要修改子窗体代码,所有逻辑都在主窗体中实现,避免子窗体依赖主窗体细节:

1. 订阅子窗体关闭事件

在主窗体打开Expenses子窗体时,订阅其FormClosed事件:

private void AbrirExpensesToolStripMenuItem_Click(object sender, EventArgs e)
{
    ExpensesForm expensesForm = new ExpensesForm();
    // 订阅子窗体关闭事件
    expensesForm.FormClosed += ExpensesForm_FormClosed;
    expensesForm.Show();
    // 启用菜单
    M_Selecao.Enabled = true;
}

2. 实现关闭事件处理逻辑

在主窗体中添加事件处理方法,子窗体关闭时禁用菜单,并取消订阅事件避免内存泄漏:

private void ExpensesForm_FormClosed(object sender, FormClosedEventArgs e)
{
    M_Selecao.Enabled = false;
    // 取消订阅事件,防止内存泄漏
    ExpensesForm closedForm = sender as ExpensesForm;
    if (closedForm != null)
    {
        closedForm.FormClosed -= ExpensesForm_FormClosed;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:02:21