winforms 如何在不改变值的情况下打开子窗体?

zynd9foi  于 2023-03-13  发布在  其他
关注(0)|答案(1)|浏览(180)

我有一个主窗体,我在主窗体中创建了一个面板,用一个按钮打开子窗体。但是当我在子窗体中更改了一些东西,我再次单击按钮从主窗体打开子窗体时,我在子窗体中所做的更改不再存在了。这是我的问题。请帮助我,谢谢。
我在主窗体中的代码:

private void btnRoom_Click(object sender, EventArgs e)
{
    FormRoom fr = new FormRoom();
    fr.TopLevel = false; 
    panelDesktopPanel.Controls.Add(fr); 
    fr.FormBorderStyle = FormBorderStyle.None; 
    fr.Dock = DockStyle.Fill; fr.BringToFront(); fr.Show(); 
    ActivateButton(sender); 
    lblTitle.Text = fr.Text;
}
lrl1mhuk

lrl1mhuk1#

实现目标非常简单,但有一个“技巧”你必须知道。因此,首先,使fr成为主窗体类的 * 成员 *,并从一开始就将其添加到panelDesktopPanelControls集合中。它的可见性设置为false,因此除非你希望它显示,否则它不会显示。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        checkBoxRoom.Appearance = Appearance.Button;
        checkBoxRoom.CheckedChanged += onCheckedChangedRoom;
        Disposed += (sender, e) =>fr.Dispose();
        panelDesktopPanel.Controls.Add(fr);
    }

    FormRoom fr = new FormRoom
    {
        Visible = false,
        TopLevel = false,
        FormBorderStyle= FormBorderStyle.None,
        Dock= DockStyle.Fill,
        BackColor= Color.Azure,
    };
    .
    .
    .
}

我提到的需要特殊处理的部分是当Form可见性将被循环多次时。因为你将FormBorderStyle设置为None,所以这个问题在你的项目中将是最小的。但是当[X]框对Close可见时,你必须非常小心,操作系统不会释放底层的窗口句柄。
为了谨慎起见,让我们确保FormRoomHandle不能以覆盖FormClosing事件的方式被销毁。

class FormRoom : Form
{
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        // Disallow close by [X] hide instead.
        FormClosing += (sender, e) =>
        {
            e.Cancel = e.CloseReason.Equals(CloseReason.UserClosing);
            Hide();
        };
    }
}

测试

出于测试目的,我将您的[Room]按钮替换为一个复选框,该复选框 * 看起来 * 像一个按钮,以便我们可以循环其可见性,并且看起来一切正常!

public partial class MainForm : Form
{
    .
    .
    .
    private void onCheckedChangedRoom(object sender, EventArgs e)
    {
        fr.Visible = checkBoxRoom.Checked;
    }
}

相关问题