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

C# 使用MVP模式处理菜单点击事件不触发问题咨询

你的代码思路符合MVP模式的职责划分要求,出现点击事件不触发的问题是事件绑定的顺序错误导致的,和MVP模式本身无关。

问题原因

C#的事件是基于多路广播委托的机制,你在构造函数中执行this.item1ToolStripMenuItem.Click += AboutMenuItemClicked;时,AboutMenuItemClicked还没有绑定任何处理方法(你是在这行代码之后才初始化Presenter,给AboutMenuItemClicked添加的处理逻辑),此时相当于给菜单项的Click事件绑定了一个空委托。后续给AboutMenuItemClicked新增订阅者时,不会同步更新到已经绑定好的菜单项Click事件的委托列表中,所以点击菜单项时不会触发Presenter的处理逻辑。

修复方案

有两种常用的修复方式,更推荐第二种:

方案1:调整绑定顺序

先初始化Presenter完成自定义事件的订阅,再绑定菜单项的Click事件到自定义事件:

public Form1()
{
    InitializeComponent();
    // 先初始化Presenter,给自定义事件添加处理方法
    m_menuBarPresenter = new MenuBarPresenter(this);
    // 再绑定菜单项点击事件到自定义事件
    this.item1ToolStripMenuItem.Click += AboutMenuItemClicked;
}

方案2:View层主动触发事件(更推荐)

不要直接把自定义事件绑定到控件事件,而是在View层的控件点击回调中主动触发对外暴露的自定义事件,这种写法避免了顺序依赖,还能自动处理空引用问题,更符合MVP模式的规范:

public partial class Form1 : Form, IMenuBarView
{
    public event EventHandler AboutMenuItemClicked;
    private MenuBarPresenter m_menuBarPresenter;

    public Form1()
    {
        InitializeComponent();
        m_menuBarPresenter = new MenuBarPresenter(this);
        // View层处理原生控件事件,转发为对外暴露的业务事件
        this.item1ToolStripMenuItem.Click += (sender, args) => 
        {
            AboutMenuItemClicked?.Invoke(sender, args);
        };
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:36:04