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

C# EventHandler跨类调用失效,外部类监听无响应求助

问题:EventHandler跨类监听失效,内部触发正常但外部无响应

我实现了一个EventHandler,预期在OpenProject方法执行完成时触发,由MainWindow类监听。测试时发现HandleProjectViewModel类内的"work inside"日志正常输出,说明类内事件触发与监听功能正常,但MainWindow类中的"work outside"日志并未输出。

以下是精简后的核心代码(已移除不影响事件处理功能的部分):

HandleProjectViewModel 代码

using System;
using System.ComponentModel;
using System.Windows.Input;
using TiaOpennessTool.Global;
using Siemens.Engineering;

namespace TiaOpennessTool.F1
{
    internal class HandleProjectViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand OpenCommand { get; }
        public event EventHandler<bool> PopupResult;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private Project _project;
        public Project Project
        {
            get { return _project; }
            set { }
        }

        public event EventHandler<ProjectOpenedEventArgs> ProjectOpenedEvent;

        public class ProjectOpenedEventArgs : EventArgs
        {
            public Project Project { get; }
            public ProjectOpenedEventArgs(Project project)
            {
                Project = project;
            }
        }

        public HandleProjectViewModel()
        {            
            OpenCommand = new RelayCommand(OpenProject);
            ProjectOpenedEvent += ProjectOpened;
        }

        private void ProjectOpened(object sender, ProjectOpenedEventArgs e)
        {
            GlobalLog.Instance.AddLogMessage("work inside");
        }

        private void OpenProject(object obj)
        {
            GlobalLog.Instance.AddLogMessage("The project has been opened.");
            ProjectOpenedEvent?.Invoke(this, new ProjectOpenedEventArgs(_project));
        }
    }
}

MainWindow 代码

using System;
using System.Windows;
using TiaOpennessTool.F1;
using TiaOpennessTool.Global;
using Siemens.Engineering;
using TiaOpennessTool.F2;

namespace TiaOpennessTool
{
    public partial class MainWindow : Window
    {
        private HandleProjectViewModel _projectVM;
        private CompileViewModel _compileVM;

        public MainWindow()
        {
            InitializeComponent();
            _projectVM = new HandleProjectViewModel();
            _projectVM.ProjectOpenedEvent += _projectVM_ProjectOpened;
        }

        private void _projectVM_ProjectOpened(object sender, HandleProjectViewModel.ProjectOpenedEventArgs e)
        {
            _compileVM = new CompileViewModel(e.Project);
            GlobalLog.Instance.AddLogMessage("Work outside");
        }
    }
}

排查思路与解决方案

  • 检查ViewModel实例一致性
    确认MainWindow中创建的_projectVM实例,是否和UI绑定的ViewModel为同一个。如果XAML中是通过DataContext直接实例化(如<Window.DataContext><f1:HandleProjectViewModel/></Window.DataContext>),那MainWindow里的_projectVM是独立实例,无法监听到UI绑定实例触发的事件。
    解决:将MainWindow中创建的_projectVM赋值给窗口DataContext,或者从DataContext中获取ViewModel实例后再绑定事件:

    public MainWindow()
    {
        InitializeComponent();
        _projectVM = (HandleProjectViewModel)DataContext;
        _projectVM.ProjectOpenedEvent += _projectVM_ProjectOpened;
    }
    
  • 检查事件绑定时机与实例生命周期
    确保事件绑定在ViewModel实例创建后、事件触发前完成。如果后续代码中重新实例化了_projectVM,之前的事件绑定会失效,需要重新绑定。

  • 统一事件触发逻辑(优化)
    遵循.NET事件标准写法,在HandleProjectViewModel中添加专门的事件触发方法,确保逻辑统一且便于调试:

    protected virtual void OnProjectOpened(Project project)
    {
        ProjectOpenedEvent?.Invoke(this, new ProjectOpenedEventArgs(project));
    }
    
    private void OpenProject(object obj)
    {
        GlobalLog.Instance.AddLogMessage("The project has been opened.");
        OnProjectOpened(_project);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:31:02