如何通过反射在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
相关产品推荐
相关产品推荐

