0

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?

tar
  • 156
  • 2
  • 13
  • 1
    Why are you using `ShowDialog`? Why not just put a panel on the main form? – Enigmativity Mar 15 '22 at 11:56
  • Owner = this.FindForm(); – Hans Passant Mar 15 '22 at 12:03
  • @Enigmativity: I want to center a modal dialogue form above a window. @HansPassant: This did not work if the owner is not set and does not solve the problem when the owner's location is `0,0`. Found a solution, see below. – tar Mar 15 '22 at 12:49
  • @tar - Yes, I understood that. Can you answer my question? – Enigmativity Mar 16 '22 at 01:31
  • @tar - Also, you can only `@` one person in each comment. Hans would not have gotten a notification. – Enigmativity Mar 16 '22 at 01:31
  • @Enigmativity: ??? How does a panel solve the positioning of a new dialogue window? – tar Mar 17 '22 at 08:28
  • @tar - It doesn't. I'm wondering why you are trying to position a dialog, when just putting a panel on the form will do the same thing (given you turn off events for the rest of the form)? – Enigmativity Mar 18 '22 at 03:57
  • @Enigmativity Because modal dialogues are used to manipulate data entries cleanly and separately since Paris kidnapped Helen of Troy. Furthermore, I doubt it to be very user friendly to display message and question dialogues inside a panel. – tar Mar 18 '22 at 17:33
  • @tar - You're asking to place a model dialog over a panel in the form. I'm suggesting to use a panel and make it model and avoid the dialog and the positioning issue. The usability is identical. – Enigmativity Mar 19 '22 at 04:36
  • @Enigmativity Sorry, but you got confused or we are talking across purposes. I asked how to position a form centered above another form (the panels do not really matter - I've mentioned them only to explain that there are subforms through panels used). This new form should neither replace the calling form nor should it have the same size as it. In fact, the dialogue form can be much larger or smaller than the form which opens it. – tar Mar 19 '22 at 17:10
  • @tar - Fair enough. You're right. I didn't understand what you were after. Indeed we were ***at cross purposes***. – Enigmativity Mar 19 '22 at 22:53

2 Answers2

1

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.

tar
  • 156
  • 2
  • 13
-1

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

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

OpenChildForm(new Form1());
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
Gonzalo10
  • 1
  • 1
  • You misunderstood the problem as your code is for handling forms within a panel control and not about centering modal dialogue forms. – tar Mar 15 '22 at 12:54