How do I ensure a form displays on the "additional" monitor in a dual monitor scenario? [duplicate]
Asked Answered
P

4

24

I have an application in which there is a form which I want to show on second screen.

Mean If application is running on screen A and when I click on menu to show Form it should display on Screen B and same with if application is running on screen B and when I click on menu to show Form it should display on Screen A.

Protractor answered 1/4, 2010 at 14:30 Comment(5)
What if there are three monitors?Indra
the app will run on dual screen only.Protractor
Are you sure? What happens when one of your users buys a third monitor? What happens if the app is used over Remote Desktop?Indra
we will provide the system with dual screen only to user:)Protractor
This question (and the accepted answer) are more specific and therefore not an exact duplicate of #1363874 . Both questions are complementary.Funkhouser
I
44

You need to use the Screen class to find a screen that the original form is not on, then set the second form's Location property based on that screen's Bounds.

For example:

var myScreen = Screen.FromControl(originalForm);
var otherScreen = Screen.AllScreens.FirstOrDefault(s => !s.Equals(myScreen)) 
               ?? myScreen;
otherForm.Left = otherScreen.WorkingArea.Left + 120;
otherForm.Top = otherScreen.WorkingArea.Top + 120;

This will work for any number of screens.

Note that it is possible that the video card is configured so that Windows sees one large screen instead of two smaller ones, in which case this becomes much more difficult.

Indra answered 1/4, 2010 at 14:32 Comment(6)
if the originator form is not available??Protractor
I have two screens set as "extended" on my Windows7. If I use your code my window remain on first screen because otherScreen.WorkingArea is always placed on (0,0); I had to use otherScreen.Bounds to move windows on top-left of second screen. Am I correct?Crossroad
More: (s => s != myScreen) is not working; I had to use (s => !s.Equals(myScreen))Crossroad
Good answer! In a short code it provides exactly what is asked for, and even a safe fallback to using the same screen if only one is available, plus a hint on how to position the Form relative to that screen. Notice that WorkingArea is the area where the form would be viewable (not hidden by e.g. the task bar), and it is equal to Bounds when there are no bars or borders (like the task bar). Notice that the task bar may actually be on the secondary screen.Funkhouser
I had to set otherForm.StartPosition = FormStartPosition.Manual for this to work.Matthei
You should use the Bounds property, as stated by @CrossroadTatman
M
22

Below is a function allowing you to display a form on any monitor. For your current scenario you can call this showOnMonitor(1);.

Essentially you have to get screen information from Screen.AllScreens and then get the dimensions of each, then place your form where you need it

function void showOnMonitor(int showOnMonitor) 
{ 
    Screen[] sc; 
    sc = Screen.AllScreens; 

    Form2 f = new Form2(); 

    f.FormBorderStyle = FormBorderStyle.None; 
    f.Left = sc[showOnMonitor].Bounds.Left; 
    f.Top = sc[showOnMonitor].Bounds.Top; 
    f.StartPosition = FormStartPosition.Manual; 

    f.Show(); 
}

Note don't forget to do validation to ensure you actually have two screens etc else an exception will be thrown for accessing sc[showOnMonitor]

Myrtlemyrvyn answered 1/4, 2010 at 14:32 Comment(2)
This still does not completely answer the question.Indra
It should be f.Left = sc[showOnMonitor].Bounds.Left; f.Top = sc[showOnMonitor].Bounds.Top;Eskridge
P
12

On the OnLoad method change the Location of the window.

protected void Form1_OnLoad(...) {
    showOnMonitor(1);
}

private void showOnMonitor(int showOnMonitor) 
{ 
    Screen[] sc; 
    sc = Screen.AllScreens; 
    if (showOnMonitor >= sc.Length) {
        showOnMonitor = 0;
    }

    this.StartPosition = FormStartPosition.Manual; 
    this.Location = new Point(sc[showOnMonitor].Bounds.Left, sc[showOnMonitor].Bounds.Top);
    // If you intend the form to be maximized, change it to normal then maximized.
    this.WindowState = FormWindowState.Normal;
    this.WindowState = FormWindowState.Maximized;
}
Punish answered 18/11, 2011 at 5:28 Comment(4)
Why not just this.Location = sc[showOnMonitor].Bounds.Location?Dirkdirks
Yes you can do that too.Punish
@Nap, Does your code work if i connect the second monitor via hdmi port?Stephanystephen
@Stephanystephen I was able to test with vga and hdmi ports.Punish
F
2

I used this for an XNA 4 Dual Screen Application (Full Screen XNA Game Window + WinForm)

In the Form_Load() method, place the following code:

var primaryDisplay = Screen.AllScreens.ElementAtOrDefault(0);  
var extendedDisplay = Screen.AllScreens.FirstOrDefault(s => s != primaryDisplay) ?? primaryDisplay;

this.Left = extendedDisplay.WorkingArea.Left + (extendedDisplay.Bounds.Size.Width / 2) - (this.Size.Width / 2);
this.Top = extendedDisplay.WorkingArea.Top + (extendedDisplay.Bounds.Size.Height / 2) - (this.Size.Height / 2);
Fissirostral answered 19/10, 2013 at 14:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.