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

如何通过反射在WeifenLuo的Dock容器内正确动态创建Form实例

问题解决方案

核心原因

你反射调用的Show方法不是WeifenLuo库提供的停靠专用重载:

  • 原有代码中反射获取的是.NET原生Form类的Show(IWin32Window owner)重载,作用是将窗体作为父窗口的附属弹窗打开,不会嵌入停靠容器
  • WeifenLuo的DockContent类专门提供了参数为DockPanel类型的Show重载,调用该方法才能将窗体嵌入停靠容器

推荐修复方案

直接调整泛型约束,不需要反射即可实现更安全的调用,修改后的代码如下:

// 泛型约束直接限定为DockContent子类,避免类型转换风险
public static void OpenForm<T>(DockPanel dockPanel, T form = null, object obj = null, bool maximized = false) where T : DockContent, new()
{
    CreateMainForm();

    // 检索已打开的窗体
    foreach (DockContent frm in dockPanel.Contents)
    {
        // 校验内容是否已存在
        if (frm.GetType() == typeof(T) && obj == null)
        {
            frm.Activate();
            return;
        }
        // 校验点击按钮对应的窗体是否已存在
        if (obj != null && frm.GetType() == obj.GetType())
        {
            frm.Activate();
            return;
        }
    }

    form ??= new T();

    if (maximized)
        form.WindowState = FormWindowState.Maximized;

    // 直接调用停靠专用Show方法
    form.Show(dockPanel);
}

特殊场景修复(必须保留反射的情况)

如果因为业务逻辑必须使用反射调用,只需修改反射获取方法的代码即可:

// 原有错误写法,获取的是原生Form的弹窗重载
// MethodInfo methodInfo = type.GetMethod("Show", new Type[] { typeof(IWin32Window) });
// 正确写法,获取停靠专用的Show重载
MethodInfo methodInfo = type.GetMethod("Show", new Type[] { typeof(DockPanel) });
methodInfo.Invoke(form, new object[] { dockPanel });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:57:02