C# Winforms:如何让 CenterParent 与 SubForms 和 ModalForms 一起运行?

C# Winforms: How to get CenterParent with SubForms and ModalForms to function?

我有一个 MainForm,面板中有一个子表单 SubLevel1。在 SubLevel1 中,我有另一个子表单 SubLevel2,它在 SubLevel1 的面板中打开。现在,从 SubLevel2 我打开一个 ModalFormShowDialog() 我想把它放在 SubLevel2 分别。 MainForm(其中 SubLevel2 通过 SubLevel1 包含)。

CenterParent 只是不起作用,我无法获得正确的(相对)位置来正确定位 ModalForm

  1. 我无法将 SubLevel2 设置为 ModalFormParent: "a top级别控件无法添加到控件”错误弹出。因此,ModalFormParent 总是 null.

  2. 当我将 SubLevel2 设置为 ModalFormOwner 时,它的位置总是 0,0 不能用于定位 ModalForm.

  3. 当我使用ownerLocation = modalForm.Owner.PointToClient(Point.Empty)时,位置不正确。

  4. 当我使用ownerLocation = modalForm.Owner.PointToScreen(Point.Empty)时,位置不正确。

在创建 SubForms 时,我按如下方式进行:

  _FormSub = new FormSub() {
    TopLevel = false,
    TopMost  = false
  };
  panelSub.Controls.Add(_FormSub);
  _FormSub.Show();

SubForm2 的代码中创建 ModalForm 时,我按如下方式进行:

  formModal = new formModal() {
    Owner = this
  };
  formModal.ShowDialog();

我需要改变什么?

通过试错找到解决方案。

创建 ModalForm 时需要将创建的 ModalForm 的 Owner 设置为调用表单的 TopLevelControl:

FormModal formModal = new FormModal() { Owner = this.TopLevelControl as Form };

这在从现有 ModalForm 创建另一个 ModalForm 时也有效(那么现有 ModalForm 本身就是 TopLevelControl)。

因此,您确保创建的 ModalForm 的 Owner 始终具有 正确的屏幕位置,您可以通过它设置 ModalForm 在其 FormLoad() 编程方法:

int centerX   = (this.Owner != null) ? this.Owner.Location.X + (this.Owner.Width  / 2) : screen.WorkingArea.Width  / 2;
int centerY   = (this.Owner != null) ? this.Owner.Location.Y + (this.Owner.Height / 2) : screen.WorkingArea.Height / 2;
int locationX = (centerX - (this.Width  / 2) > 0) ? centerX - (this.Width  / 2) : 0;
int locationY = (centerY - (this.Height / 2) > 0) ? centerY - (this.Height / 2) : 0;

if (locationX > screen.WorkingArea.Width)  { locationX = screen.WorkingArea.Width  - this.Width;  }
if (locationY > screen.WorkingArea.Height) { locationY = screen.WorkingArea.Height - this.Height; }

this.Location      = new Point(locationX, locationY);
form.StartPosition = FormStartPosition.Manual;

这确保了 ModalForm 在调用窗体上方居中打开而不使用 ParentCenterParent - 或 - (如果未设置 Owner)居中不使用 CenterScreen.

的屏幕

还确保 ModalForm 始终在实际屏幕的边界内打开。

我有一些东西可以帮助你:

private Form Activeform = null;

private void OpenChildForm(Form childForm)
{
    if (Activeform != null)
    {
        Activeform.Close();
    }

    Activeform = childForm;
    childForm.Visible = false;
    childForm.BackColor = Color.FromArgb(32, 30, 45);
    childForm.TopLevel = false;
    childForm.FormBorderStyle = FormBorderStyle.None;
    childForm.Dock = DockStyle.Fill;
    panel1.Controls.Add(childForm);
    panel1.Tag = childForm;
    childForm.BringToFront();
    childForm.Show();
}

这样你就有了可重用的方法。 你会怎么称呼它的例子

OpenChildForm(new Form1());