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
相关产品推荐
相关产品推荐

