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

如何在WinForms(.Net4.6.1)中订阅Excel的Workbook.SheetActivate事件?

在.NET 4.6.1 WinForms中动态订阅Excel SheetActivate事件的解决方案

问题描述

我希望将Excel应用作为动态对象使用(不依赖特定版本),订阅其Workbook.SheetActivate事件。

实例化与事件处理代码

public static dynamic NewInstance()
{
    Type excelType = Type.GetTypeFromProgID("Excel.Application");
    return Activator.CreateInstance(excelType);
}

private static void Excel_SheetActivate(dynamic Sh)
{
    Sh.Protect("test");
}

场景差异

  • .NET 5控制台应用:运行以下代码完全正常
static void Main(string[] args)
{
    dynamic excel = NewInstance();
    excel.SheetActivate += new Action<object>((obj) => Excel_SheetActivate(obj));
}
  • .NET 4.6.1 WinForms应用:运行以下代码报错
public Form1()
{
    InitializeComponent();

    dynamic excel = NewInstance();
    excel.SheetActivate += new Action<object>((obj) => Excel_SheetActivate(obj));
}

报错信息

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'The System.Action<object> type cannot be implicitly converted to Microsoft.Office.Interop.Excel.AppEvents_SheetActivateEventHandler'.

对象类型差异

Console:  dynamic {System.__ComObject}
Winforms: dynamic {Microsoft.Office.Interop.Excel.ApplicationClass}

解决方案

问题根源是.NET Framework WinForms项目中,动态对象实际是强类型的Microsoft.Office.Interop.Excel.ApplicationClass,它的SheetActivate事件要求使用专属的AppEvents_SheetActivateEventHandler委托,而非通用的Action<object>。以下是两种解决方式:

方法一:完全动态创建委托(无版本依赖)

通过反射获取Excel事件委托类型,再创建委托绑定到处理方法,全程不依赖特定版本的Interop引用:

public Form1()
{
    InitializeComponent();

    dynamic excel = NewInstance();
    // 获取Excel SheetActivate事件对应的委托类型
    Type eventHandlerType = Type.GetTypeFromProgID("Excel.AppEvents_SheetActivateEventHandler");
    // 创建委托实例,绑定到静态的Excel_SheetActivate方法
    Delegate handler = Delegate.CreateDelegate(
        eventHandlerType, 
        typeof(Form1).GetMethod("Excel_SheetActivate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)
    );
    // 订阅事件
    excel.SheetActivate += handler;
}

方法二:显式使用Interop委托类型(需引用程序集)

如果项目中已引用Excel Interop程序集,可直接使用对应的委托类型:

public Form1()
{
    InitializeComponent();

    dynamic excel = NewInstance();
    excel.SheetActivate += new Microsoft.Office.Interop.Excel.AppEvents_SheetActivateEventHandler(Excel_SheetActivate);
}

注意:方法一完全满足“不依赖特定版本”的需求,方法二则需要确保引用的Interop版本与目标环境兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:31:00