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

为运行时加载的DLL中的WinForm附加事件处理程序

解决反射加载WinForm DLL时绑定自定义事件的问题

问题原因

反射创建的窗体实例编译时类型为Object,编译器无法识别该类型上定义的ImDone自定义事件,直接通过实例访问事件会触发编译报错。

解决方案

以下两种方式可实现事件绑定并获取返回参数:

方法1:纯反射实现事件绑定与参数解析

完全依赖反射机制,无需提前引用目标DLL,适合无法预知事件参数类型的场景:

  1. 定义事件处理方法,用object接收事件参数:
private void HandleImDone(object sender, object e)
{
    // 通过反射获取事件参数中的RetVal属性
    var retValProp = e.GetType().GetProperty("RetVal");
    if (retValProp != null)
    {
        var returnValue = retValProp.GetValue(e);
        // 在这里处理返回参数
        Console.WriteLine($"获取到返回值:{returnValue}");
    }
}
  1. 反射加载DLL、创建实例并绑定事件:
// 加载网络路径下的目标DLL
var targetAssembly = Assembly.LoadFrom(@"\\network-path\WinFormApp.dll");
// 获取FrmMain的类型信息
var frmMainType = targetAssembly.GetType("WinFormApp.FrmMain");
// 创建窗体实例
var formInstance = Activator.CreateInstance(frmMainType);

// 获取ImDone事件的EventInfo对象
var imDoneEvent = frmMainType.GetEvent("ImDone");
if (imDoneEvent != null)
{
    // 创建与事件委托签名匹配的委托实例
    var handlerDelegate = Delegate.CreateDelegate(
        imDoneEvent.EventHandlerType,
        this,
        typeof(YourMainClass).GetMethod("HandleImDone", BindingFlags.NonPublic | BindingFlags.Instance)
    );
    // 绑定事件处理程序
    imDoneEvent.AddHandler(formInstance, handlerDelegate);
}

// 调用Show方法显示窗体
frmMainType.GetMethod("Show").Invoke(formInstance, null);

方法2:使用dynamic简化操作

若可接受运行时类型检查,dynamic能大幅简化代码编写:

  1. 定义事件处理方法,用dynamic接收事件参数:
private void HandleImDone(object sender, dynamic e)
{
    // 直接访问RetVal属性,由dynamic在运行时解析类型
    var returnValue = e.RetVal;
    // 处理返回参数
    Console.WriteLine($"获取到返回值:{returnValue}");
}
  1. 加载DLL并绑定事件:
var targetAssembly = Assembly.LoadFrom(@"\\network-path\WinFormApp.dll");
var frmMainType = targetAssembly.GetType("WinFormApp.FrmMain");
// 用dynamic声明实例,绕过编译时类型检查
dynamic formInstance = Activator.CreateInstance(frmMainType);
// 直接绑定事件
formInstance.ImDone += HandleImDone;
// 显示窗体
formInstance.Show();

关键注意事项

  • 事件处理方法的签名必须与目标DLL中ImDone事件的委托签名完全一致(参数数量、类型、返回值需严格匹配)。
  • 若目标DLL使用自定义委托类型,反射方式中需确保Delegate.CreateDelegate使用imDoneEvent.EventHandlerType指定的委托类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:15:06