在Winform C#中的弹出窗口

36

我正在开发一个项目,需要弹出窗口。但问题是我希望通过表单设计器在这个弹出窗口中添加文本框等。

基本上我有一个按钮,当你点击它时,会打开另一个我在表单设计器中设计的窗口。

我已经做了一些谷歌搜索,但还没有找到我需要的东西,所以我希望你们能帮助我!


你能否提供一些示例代码让我们来解读一下? - Sean
你最好自己创建一个表单,以便完全按照你想要的方式进行操作。 - gwin003
6个回答

45

在 Visual Studio 中创建另一个表单(我们称之为 formPopup)。在按钮处理程序中编写以下代码:

var formPopup = new Form();
formPopup.Show(this); // if you need non-modal window
如果你需要一个非模态窗口,请使用:formPopup.Show();。如果您需要一个对话框(因此,您的代码将在调用此方法时挂起,直到您关闭打开的窗体),请使用:formPopup.ShowDialog()

代码片段中的注释应该是:// 如果您需要非模态窗口 - AdamBT

8

这并不容易,因为基本上Windows Forms不支持弹出窗口。虽然Windows Forms是基于Win32的,在Win32中支持弹出窗口。 如果您接受一些技巧,下面的代码将帮助您设置弹出窗口。您可以决定是否要好好利用它:

class PopupWindow : Control
{
    private const int WM_ACTIVATE = 0x0006;
    private const int WM_MOUSEACTIVATE = 0x0021;

    private Control ownerControl;

    public PopupWindow(Control ownerControl)
        :base()
    {
        this.ownerControl = ownerControl;
        base.SetTopLevel(true);
    }

    public Control OwnerControl
    {
        get
        {
            return (this.ownerControl as Control);
        }
        set
        {
            this.ownerControl = value;
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;

            createParams.Style = WindowStyles.WS_POPUP |
                                 WindowStyles.WS_VISIBLE |
                                 WindowStyles.WS_CLIPSIBLINGS |
                                 WindowStyles.WS_CLIPCHILDREN |
                                 WindowStyles.WS_MAXIMIZEBOX |
                                 WindowStyles.WS_BORDER;
            createParams.ExStyle = WindowsExtendedStyles.WS_EX_LEFT |
                                   WindowsExtendedStyles.WS_EX_LTRREADING |
                                   WindowsExtendedStyles.WS_EX_RIGHTSCROLLBAR | 
                                   WindowsExtendedStyles.WS_EX_TOPMOST;

            createParams.Parent = (this.ownerControl != null) ? this.ownerControl.Handle : IntPtr.Zero;
            return createParams;
        }
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr SetActiveWindow(HandleRef hWnd);

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_ACTIVATE:
                {
                    if ((int)m.WParam == 1)
                    {
                        //window is being activated
                        if (ownerControl != null)
                        {
                            SetActiveWindow(new HandleRef(this, ownerControl.FindForm().Handle));
                        }
                    }
                    break;
                }
            case WM_MOUSEACTIVATE:
                {
                    m.Result = new IntPtr(MouseActivate.MA_NOACTIVATE);
                    return;
                    //break;
                }
        }
        base.WndProc(ref m);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.FillRectangle(SystemBrushes.Info, 0, 0, Width, Height);
        e.Graphics.DrawString((ownerControl as VerticalDateScrollBar).FirstVisibleDate.ToLongDateString(), this.Font, SystemBrushes.InfoText, 2, 2);
    }
}

多试试,你需要调整它的位置和大小。如果使用不当,则不会显示任何内容。


很好,这个能从UserControl继承吗还是会有问题?重写wm_mouseactivate的目的是什么?最后一个问题,我可以使用this.Activate()来保持与mono兼容性吗,还是因为这不是一个窗体而无法使用?谢谢。 - Behrooz
1
不了解用户控件,它已经从控件本身派生出来,因此具有比控件更专业的行为,但它可能有效。我也从未在Mono上测试过这个,对于dll导入我也不确定更具体的情况。简而言之,它利用了底层的win32 api系统。 - Philip Stuyck
我看到另一个问题有这个答案的副本。希望没有更多(它们几乎同时发布,这很可疑)。通常情况下,你应该将问题标记为重复,而不是复制/粘贴你的答案。 - Sinatr
我不确定这是否是操作员想要的。既然这不能作为答案被接受,我认为我的假设是正确的。操作员在弹出窗口方面意思不同。 - Philip Stuyck

5

C#中的表单是继承Form基类的类。

通过创建该类的实例并调用ShowDialog()方法,您可以显示一个弹出窗口。


3

如果你想在点击按钮时创建一个新的表单,下面的代码可能对你有些帮助:

private void settingsButton_Click(Object sender, EventArgs e)
{
    // Create a new instance of the Form2 class
    Form2 settingsForm = new Form2();

    // Show the settings form
    settingsForm.Show();
}

从这里开始,您还可以使用“Show Dialog”方法

来进行操作。


1
我正在使用这种方法。
添加一个要弹出的表单,添加所需的所有控件。 在代码中,您可以处理用户输入并将结果返回给调用者。 要弹出表单,只需创建表单的新实例并使用show方法。
/* create new form instance. i am overriding constructor to allow the caller form to set the form header */ 
var t = new TextPrompt("Insert your message and click Send button");
// pop up the form
t.Show();
if (t.DialogResult == System.Windows.Forms.DialogResult.OK)
{ 
  MessageBox.Show("RTP", "Message sent to user"); 
}

1
"但是问题在于,我还希望能够通过表单设计器在此弹出窗口中添加文本框等内容。"
从您的描述中不清楚您在开发过程中处于哪个阶段。如果您还没有想到如何创建新的表单,可以点击“项目-->添加Windows窗体”,然后输入表单名称并点击“添加”按钮。现在,您可以像预期的那样向表单添加控件。
当需要显示它时,请遵循其他帖子的建议创建一个实例,并相应地调用Show()或ShowDialog()。

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