将一个Windows窗体设置为另一个Windows窗体的MDI子窗体(或等效的操作)

4
我有两个Windows窗体应用程序,让我们称它们为FormA.exe(父级)和FormB.exe(子级)。FormB.exe是一个可以单独运行的应用程序。 FormA.exe是另一个应用程序,其功能之一是调用FormB.exe
我有两个应用程序的源代码,并且我可以修改它们。
目前,每当FormA.exe想要调用FormB.exe时,我会使用Process类启动FormB.exe进程。问题在于:
  1. 我不知道如何在这两个窗体之间传递消息。
  2. FormB.exeFormA调用时,它将出现为用户的另一个应用程序,独立于FormA.exe,但我希望它在FormA下出现为单个应用程序,其中FormB为MDI子级。
  3. FormB本身是MDI。因此,如果我将其作为MDI加载,则会出现错误System.ArgumentException:Form cannot be both an MDI child and MDI parent
  4. 如果我不以MDI方式加载,则我的FormB无法正常运行。换句话说,FormA的整个目的都失去了。
除了将FormB设置为FormA的MDI子级之外,是否有其他方法可以使一个Winform应用程序完全包含在另一个Winform应用程序中,并使它们相互通信?

更好的方法是将两个表单放在同一个进程中,由于您拥有代码,因此可以这样做。 - David Heffernan
@David,这是一项巨大的工作。 - Conditional Change
可能会有很多工作,但至少有成功的前景。 - David Heffernan
2个回答

1

我同意Noel的观点

有很多方法可以实现你想要的功能。其中一种方法是使用System.Reflection

在formA中可以这样做

 Assembly a = Assembly.LoadFrom("WindowsApplication1.exe");
        Form frm = a.CreateInstance("WindowsApplication1.FormB") as Form;
        frm.MdiParent = this;
        frm.Show();

@Conditional 再次更改,有几种方法,但我方便的方式是实现接口 例如 IMdiParent formA=this.parent as IMdiParentIChild formB=frm as IChild - Subhash Lama
@Subhash,嗯,你的代码不起作用是因为FormB本身就是一个MDI表单,请参见更新的问题。 - Conditional Change
为什么你想让 FormB 成为 FormA 的子窗体?只需使用 ShowShowDialog 方法即可。 - Subhash Lama
我想你要找的可以在这里找到。 - Subhash Lama
@Conditional Change,你从我的上一条评论中得到了答案吗? - Subhash Lama
显示剩余9条评论

0
你可以从FormA.exe向FormB.exe添加项目引用,并以编程方式将formb作为mdi子窗体加载到forma中。
然后,你可以轻松地在它们之间传递消息。FormB.exe仍然可以作为应用程序单独调用,只需将其保留为Windows应用程序而不是Windows库项目即可。

@Noel,你能再明确一些吗?你是说我可以使用System.Reflection.Assembly.LoadFrom吗?那么我该如何在两个应用程序之间传递消息呢? - Conditional Change
要传递消息,只需在FormB类中调用方法,没有任何神奇的事情发生,它只是被视为另一个dll。 - Noel Kennedy
如果你正在寻找一些用于智能客户端内部通信的模式,请搜索事件聚合器模式。有各种框架包含了可供使用的实现,例如Prism、CAB、caliburn。 - Noel Kennedy
我认为,作为一个MDI窗体,它不能有父级,无论你如何将FormB加载到FormA中,你都无法设置FormB的父级为FormA,除非改变它的工作方式,即将作为FormB子级的窗体加载到FormA的窗体集合中。这可能是微不足道的,也可能是非常具有侵入性的,这取决于FormA和FormB的编码方式。 - Noel Kennedy
没有看到你的应用程序长什么样子,很难知道如何做。例如,您可以将FormB中的菜单栏加载到FormA中。您可以将FormB中的单个窗体类加载到FormA的mdi窗口中,而不是加载到FormB的mdi窗口中。如果您无法像这样做,则可以尝试通过在与FormA完全相同的位置上加载没有任何窗口装饰的FormB来伪造它。我怀疑这样做不会起作用...例如,如果用户移动FormA,FormB将不在正确的位置。它们都将在任务栏中有条目,并且其中一个基本上显示在另一个之上。 - Noel Kennedy
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接