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

Time:03-15

I have a MainForm with a subform SubLevel1 within a panel. In SubLevel1 I have another subform SubLevel2 which is opened in a panel within SubLevel1. Now, from SubLevel2 I am opening a ModalForm with ShowDialog() and I want to center it above SubLevel2 resp. MainForm (in which SubLevel2 is included through SubLevel1).

CenterParent just does not work and am not able to get the correct (relative) location to position the ModalForm correctly:

  1. I am not able to set SubLevel2 as Parent of the ModalForm: "a top level control can not be added to a control" error pops up. Therefore, Parent of the ModalForm is always null.

  2. When I set SubLevel2 as Owner of ModalForm, it always has the location 0,0 which cannot be used to position the ModalForm.

  3. When I use ownerLocation = modalForm.Owner.PointToClient(Point.Empty) the position is not correct.

  4. When I use ownerLocation = modalForm.Owner.PointToScreen(Point.Empty) the position is not correct.

When creating the SubForms I do it as follows:

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

When creating the ModalForm within the code of SubForm2 I do it as follows:

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

What do I need to change?

CodePudding user response:

I have something that could help you:

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();
        }
        else
        {
            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();
        }

This way you have the method reusable. Example of what you would call it

OpenChildForm(new Form1());

CodePudding user response:

Found a solution by try & error.

When creating a ModalForm you need to set the Owner of the created ModalForm to the TopLevelControl of the calling form:

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

This also works when creating another ModalForm from an existing ModalForm (then the existing ModalForm itself is the TopLevelControl).

Thereby, you ensure that the Owner of the created ModalForm always has the correct screen location by which you can set the centered position of the ModalForm within its FormLoad() method programmatically:

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;

This ensures that the ModalForm is either opened centered above the calling form without the use of Parent and CenterParent -or- (if no Owner has been set) centered on the screen without the use of CenterScreen.

It is also ensured that the ModalForm will always be opened within the boundaries of the actual screen.

  • Related