From 5eb0077221d15e9a551921158afd177369a738ea Mon Sep 17 00:00:00 2001
From: SugarChes <103551815+SugarChes@users.noreply.github.com>
Date: Tue, 1 Sep 2026 15:43:24 +0800
Subject: [PATCH] fix(legacy): defer WinForms module showing for WPF host
---
插件库/Lskj.Main/Model/Manager.cs | 105 ++++++++++++++++++++++++++++--
1 file changed, 100 insertions(+), 5 deletions(-)
diff --git a/插件库/Lskj.Main/Model/Manager.cs b/插件库/Lskj.Main/Model/Manager.cs
index 9733673..bab4e66 100644
--- a/插件库/Lskj.Main/Model/Manager.cs
+++ b/插件库/Lskj.Main/Model/Manager.cs
@@ -40,6 +40,18 @@ namespace Lskj.Main.Model
///
public sealed class Manager
{
+ ///
+ /// Controls when a managed WinForms module is shown. The classic
+ /// shell keeps the original immediate behavior; the WPF compatibility
+ /// host can create the page first, attach it to WindowsFormsHost, and
+ /// show the form after the native host is ready.
+ ///
+ public enum ModuleOpenMode
+ {
+ Immediate,
+ DeferredForWpf
+ }
+
///
/// 主程序
///
@@ -287,6 +299,29 @@ namespace Lskj.Main.Model
/// The URL parameters.
public static void OpenModule(string menuId, string menuName, string dllName, string modelFlag, string urlParams)
+ {
+ OpenModule(
+ menuId,
+ menuName,
+ dllName,
+ modelFlag,
+ urlParams,
+ ModuleOpenMode.Immediate);
+ }
+
+ ///
+ /// Opens a managed WinForms module with an explicit show policy.
+ /// DeferredForWpf creates and registers the native page without
+ /// running Form.Show; the WPF compatibility layer must later call
+ /// ShowDeferredModule after attaching the page to its host.
+ ///
+ public static void OpenModule(
+ string menuId,
+ string menuName,
+ string dllName,
+ string modelFlag,
+ string urlParams,
+ ModuleOpenMode openMode)
{
string openingModuleKey = null;
bool ownsOpeningGate = false;
@@ -440,7 +475,7 @@ namespace Lskj.Main.Model
else
{
// 打开module程序
- AddModuleToTab(module, args);
+ AddModuleToTab(module, args, openMode);
}
}
}
@@ -459,6 +494,42 @@ namespace Lskj.Main.Model
}
+ ///
+ /// Shows a module that was opened with DeferredForWpf. The page and
+ /// form must already have been registered by AddModuleToTab; this
+ /// method only owns the activation step and then selects the page.
+ ///
+ public static bool ShowDeferredModule(string moduleId)
+ {
+ if (string.IsNullOrWhiteSpace(moduleId))
+ return false;
+
+ DllModule module;
+ if (!ModuleForms.TryGetValue(moduleId, out module) || module == null)
+ return false;
+
+ Form form = module.ModuleForm as Form;
+ if (form == null || form.IsDisposed)
+ return false;
+
+ if (!form.Visible)
+ form.Show();
+
+ if (form.IsDisposed)
+ return false;
+
+ XtraTabPage page = ERPInfo.Instance.ModulePages.FirstOrDefault(
+ item => item != null &&
+ string.Equals(
+ Convert.ToString(item.Tag),
+ moduleId,
+ StringComparison.OrdinalIgnoreCase));
+ if (page != null)
+ ERPInfo.Instance.SelectModulePage(page);
+
+ return true;
+ }
+
private static string BuildBsMenuUrl(string dllName, string dllCoid)
{
return string.Format(
@@ -518,6 +589,14 @@ namespace Lskj.Main.Model
/// The module.
/// The arguments.
public static void AddModuleToTab(DllModule module, string[] args)
+ {
+ AddModuleToTab(module, args, ModuleOpenMode.Immediate);
+ }
+
+ private static void AddModuleToTab(
+ DllModule module,
+ string[] args,
+ ModuleOpenMode openMode)
{
string guid = null;
XtraTabPage tp = null;
@@ -641,7 +720,11 @@ namespace Lskj.Main.Model
form.TopLevel = isQuickLoad;
//form.Location = new Point(0, 0);
form.Dock = DockStyle.Fill;//客户需要缩放
- form.AutoSize = true;
+ // A WPF WindowsFormsHost supplies the size. Letting the
+ // native Form participate in content-driven AutoSize causes
+ // a measure/reparent cycle to collapse split containers while
+ // the host is still being attached.
+ form.AutoSize = openMode != ModuleOpenMode.DeferredForWpf;
//form.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
//form.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - MinusTheHeight;
form.FormBorderStyle = FormBorderStyle.None;
@@ -666,7 +749,10 @@ namespace Lskj.Main.Model
//module.Tag = "1";
module.Tag = guid;
module.ModuleForm = form;
- form.Show();
+ if (openMode != ModuleOpenMode.DeferredForWpf)
+ {
+ form.Show();
+ }
if (args != null && !string.IsNullOrEmpty(args[4] + ""))
{
//2026-08-08 pz说把SearchCondFormModuleCode判断去掉,不要这个功能
@@ -689,8 +775,17 @@ namespace Lskj.Main.Model
}
ERPInfo.Instance.AddModulePage(tp);
- ERPInfo.Instance.SelectModulePage(tp);
- ModuleForms.Add(guid, module);
+ if (openMode == ModuleOpenMode.DeferredForWpf)
+ {
+ // Register before returning so a WPF dispatcher callback
+ // can activate the form after the Host has been attached.
+ ModuleForms.Add(guid, module);
+ }
+ else
+ {
+ ERPInfo.Instance.SelectModulePage(tp);
+ ModuleForms.Add(guid, module);
+ }
//LastModuleForm.Add(module);
//Lskj.Main.Model.AutoSizeChange.ControllInitializeSize(form);//调整控件大小