Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamically positioning a form/dialog, whilst also keeping it all on one monitor/screen

0.00/5 (No votes)
25 Aug 2015 1  
Constraining a form/dialog to a single monitor

Introduction

Sometimes you want a little more "smarts" when it comes to dynamically placing a form or dialog box, so that it doesn't position some of the form to the right or below the physical monitor, and it doesn't span monitors (in a multi-monitor setup), in much the same way as a ContextMenuStrip.

Background

I wrote this primarily for the "right-click shows dialog box" function, but it probably has other uses too. I have multiple monitors, and I just don't like seeing a dialog box split across 2 monitors.

Using the code

I want to right-click on the background in a group box. Visual Studio doesn't expose the event for this, so I had to add it into my main form's load.

        private void frmMain_Load(object sender, EventArgs e)
        {
            //this can go anywhere in the form load
            this.groupBoxTest.Click +=
                new EventHandler(this.groupBoxTest_Click);

Next is the code to handle the click event. 

        private void groupBoxTest_Click(object sender, EventArgs e)
        //Note that VisualStudio doesn't generate the click event code for a group box.
        //The hook is at the end of frmMain_Load.
        {
            GroupBox me = (GroupBox)sender;

            //The EventHandler builds an EventArgs as the second parameter,
            //but ideally I'd like a MouseEventArgs, so I simply cast e to em.
            MouseEventArgs em = (MouseEventArgs)e;

            if (em.Button == MouseButtons.Right)
            {
                frmSettings newFrmSettings = new frmSettings(this);
                MoveFormToRelativeLocation(me, new Point(em.X, em.Y), newFrmSettings);

                //Any other changes to the dialog box can go here
                //(setting text or whatever)

                newFrmSettings.ShowDialog();
            }

        }

Finally comes the location manager stuff. I actually put this in my ScreenHandler class, but I've presented it here without that reference.

        private void MoveFormToRelativeLocation(Control sender, Point pointInSender, Form form)
        {
            form.StartPosition = FormStartPosition.Manual;

            Point formTL = sender.PointToScreen(pointInSender);

            Screen myScreen = Screen.FromPoint(formTL);

            Point ScreenBR = new Point(
                myScreen.WorkingArea.Left + myScreen.WorkingArea.Width,
                myScreen.WorkingArea.Top + myScreen.WorkingArea.Height);

            if (formTL.X + form.Width > ScreenBR.X) formTL.X = ScreenBR.X - form.Width;
            if (formTL.Y + form.Height > ScreenBR.Y) formTL.Y = ScreenBR.Y - form.Height;
            if (formTL.X < 0) formTL.X = 0;
            if (formTL.Y < 0) formTL.Y = 0;

            form.Location = formTL;
        }

 

History

V1 20150826 082600

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here