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.groupBoxTest.Click +=
new EventHandler(this.groupBoxTest_Click);
Next is the code to handle the click event.
private void groupBoxTest_Click(object sender, EventArgs e)
{
GroupBox me = (GroupBox)sender;
MouseEventArgs em = (MouseEventArgs)e;
if (em.Button == MouseButtons.Right)
{
frmSettings newFrmSettings = new frmSettings(this);
MoveFormToRelativeLocation(me, new Point(em.X, em.Y), newFrmSettings);
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