在C#中嵌入一个WinForm到另一个WinForm中

15

是否可以将一个 Windows 窗体嵌入到另一个 Windows 窗体中?

我在 Visual Studio 中创建了一个 Windows 窗体以及它的所有相关行为。

现在,我想创建另一个包含选项卡视图的 Windows 窗体,并将第一个窗体嵌入到选项卡视图中。这可行吗?

7个回答

20

免责声明

这种方法在我的应用程序中得到了广泛的使用,因此它可以工作。但是,要注意,如果您将嵌入深入进行,最好采用用户控件的方式,以避免出现问题。请注意。


是的,这是可能的。以下是实现方法:

public static void ShowFormInContainerControl(Control ctl, Form frm)
{
    frm.TopLevel = false;
    frm.FormBorderStyle = FormBorderStyle.None;
    frm.Dock = DockStyle.Fill;
    frm.Visible = true;
    ctl.Controls.Add(frm);
}

我将其放在一个类库中,然后从我想要嵌入的表单中这样调用它。

public FrmCaseNotes FrmCaseNotes;
FrmCaseNotes = new FrmCaseNotes();
WinFormCustomHandling.ShowFormInContainerControl(tpgCaseNotes, FrmCaseNotes);

我希望在嵌入在表单FrmCaseNotes中的控件tpgCaseNotes上进行操作。
在这种情况下,该控件是来自我所调用的表单上的选项卡页。


14

不能直接这样做。您可以创建一个用户控件,将表单中的所有代码移动到该用户控件中,并在两个表单中使用它。您可能需要更改一些来自表单的代码,但可能不需要太多。


1
将所有共同点重构为一个用户控件,以便您可以共享。 - Gishu
12
我会为误导性信息打**-1分,因为直接在一个表单中嵌入另一个表单是完全有可能的。但他问道“是否可能...”,我通过经验学到,这是一件非常糟糕的想法/噩梦级别的工作,最好让人们认为这是不可能的...;-) - Refracted Paladin
作为 C# 的新手,我尝试了以下方法和 Refracted Paladin 的以下方法,它们都起作用了。用户控件方法允许表单设计人员在设计时查看嵌入式表单,而直接嵌入表单则不允许,需要一些视觉方面的处理。显然,如果应用程序已经有表单编写,我会采取 Refracted Paladin 的方法,但对于新的工作,我会采取这个解决方案。 - Richard Crossley

5
用用户控件而不是表单来实现这一点。这就是用户控件的用途。这种技术可以用于很多用户界面技巧,比如向导(控件可以在向导和应用程序的其他部分之间共享),带有树形控件的资源管理器样式浏览器以及基于所选节点交换控件。我曾经做过很多使用用户控件和框架来实现资源管理器、向导和其他类型表单的应用程序架构工作(甚至追溯到VB6)。作为一种方法,它非常有效。

3

假设您有两个Winform项目:win1和win2。您想要将win2嵌入到win1中。

解决方案:

打开win2项目,并将输出类型更改为“类库”(在应用程序选项卡中)。

打开win1项目,并将win2 dll项目添加为win1项目的引用。 进入win1代码,并加入以下内容:

        win2.Form1 formI = new win2.Form1();
        formI.TopLevel = false;
        formI.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        formI.Size = this.Size;
        formI.BringToFront();
        formI.Visible = true;
        this.Controls.Add(formI);

0
using System.Runtime.InteropServices;
class EmbedForm{
    [DllImport("user32.dll")]
    public extern IntPtr SetParent(IntPtr hWndChild, hWndNewParent);
    //code, code, code...
}

用法:EmbedForm.SetParent(ChildForm.Handle, ParentForm.Handle)


0
你可以尝试使用SetParent() API调用,虽然我自己没有验证过它是否有效。如果这不起作用,Mendlet上面的解决方案可能是你最好的选择。

0
最好的方法是创建一个UserControl或者简单地创建一个面板,并在面板属性中打开自动滚动功能,然后将所需元素放入您选择的表单中。您可能需要更改一些代码,但这是最简单的方法。

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

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