1

Disclaimer: I know answers have already been provided for a similar question however these do not appear to be working for me.

I have an application which uses a main form with an MDIClient; I want to show a dialog which allows the user to enter a value; this dialog is to show in the center of the MDIChild form from which the dialog is called.

I have already looked at the following solution:

C# - Show Dialog box at center of its parent

However, unless there is an application-related discrepancy with my solution, this seems to have some fundamental issues.

It is suggested that the following would achieve this:

private void OpenForm(Form parent)
{
    FormLoading frm = new FormLoading();
    frm.Parent = parent;
    frm.StartPosition = FormStartPosition.CenterParent;
    frm.ShowDialog();
}

This however, has the following issue:

When I try and implement this, when stepping through the code, as soon as it hits the line to set the form Parent, the following exception occurs:

Top-level control cannot be added to a control.

N.B. Unless all Forms initialise with a TopLevel value of true, this value doesn't seem to be set anywhere!

Okay, so; we'll set the TopLevel to false to allow the Parent form to be set as the Parent of the dialog. Assuming I do this, when it hits the line to ShowDialog():

Form that is not a top-level form cannot be displayed as a modal dialog box. Remove the form from any parent form before calling showDialog.

And therein lies my quagmire; the dialog form seems to NEED to NOT be a TopLevel form in order to have a Parent but then simultaneously needs to be a TopLevel form so it can be shown as a dialog...

Final note, I do not think I should have to set the 'StartPosition' of the form that I want to have as the dialog as this is already set in the InitializeComponent() part of the form; nevertheless, I've tried explicitly setting this in the function and it makes no difference.

Community
  • 1
  • 1
Your_Unequal
  • 246
  • 1
  • 5
  • 17
  • hi, the ShowDialog had overload to set the owner/parent of the form. You need to set the start position of FormLoading with the from itself either in design time or in Form Load event on run time. – Dr. Stitch May 13 '16 at 00:25
  • Thanks for the suggestion; I've tried using the overload but I still get told that I can't show a form that isn't a Top Level form as a dialog. I've tried setting the StartPosition to CentreParent in the constructor, the Load Event and the Shown Event but this does not have an impact on the location; if still keeps showing in the centre of the screen i.e. thinks the main form is still the Parent. – Your_Unequal May 13 '16 at 02:54

1 Answers1

2

You can position the dialog form manually:

    private void invokeDialogButton_Click(object sender, EventArgs e)
    {
        var dialogForm = new DialogForm();
        dialogForm.StartPosition = FormStartPosition.Manual;

        //Get the actual position of the MDI Parent form in screen coords
        Point screenLocation = Parent.PointToScreen(Parent.Location);

        //Adjust for position of the MDI Child form in screen coords
        screenLocation.X += Location.X;
        screenLocation.Y += Location.Y;

        dialogForm.Location = new Point(screenLocation.X + (Width - dialogForm.Width) / 2, 
                                        screenLocation.Y + (Height - dialogForm.Height) / 2);

        dialogForm.ShowDialog(this);
    }

Take a look at this working example project on my Github page (Visual Studio 2015 Community Edition project).

CoolBots
  • 4,770
  • 2
  • 16
  • 30
  • This sort of works in as much as the dialog is nearly centered; however, each time the dialog is spawned, it seems to move slightly further down and to the right? I've stepped through the code and the Location Property of the child form isn't changing but PointToScreen is returning a different X and Y value each time, even though it has the same input values? – Your_Unequal May 13 '16 at 03:01
  • I added a button to the MDI Child form (instead of loading via `Form_Shown` event handler), so I can check in various positions. I am not seeing the behavior you're describing in terms of `PointToScreen` being inconsistent; however, I did find a bug in my answer (apparent when the MDI Child is moved significantly from starting point). I updated my answer with correct code. – CoolBots May 13 '16 at 19:26
  • I have fixed the issue with the dialog moving slightly every time it's shown and I've also implemented the addition you've made to your answer; unfortunately, what seems to be happening is that a small movement to the form results in a much larger movement for the dialog. For example, when the form is right up in the top left, the dialog appears near the center of the form; however, by the time you've moved the form half way across the screen, the dialog appears off the screen! If there was a way to upload a video I could demonstrate it in a much better way... – Your_Unequal May 14 '16 at 15:38
  • Just making sure - you saw I changed the way `screenLocation` is obtained, right? It's based on MDIParent position. – CoolBots May 14 '16 at 17:40
  • I posted a link to working code sample (Github repo) in my answer - see if you can adapt it to your project. I tested moving both the MDI Parent window, the MDI Child window within the parent, etc. - the dialog comes up centered. – CoolBots May 14 '16 at 20:10
  • Many thanks for going to so much effort; I've managed to adapt the example to my project and this appears to have done it; looking at the changes made between my code and your example, you're bang on with the last check; I was calling PointToScreen() on the dialog owner itself, not the dialog owner's parent. There were also another couple of areas that were throwing the position off but they were problems within the dialog constructor itself, which I've also fixed. – Your_Unequal May 16 '16 at 00:45