How do I determine which monitor my .NET Windows Forms program is running on?

45,458

Solution 1

You can get an array of Screens that you have using this code.

Screen[] screens = Screen.AllScreens;

You can also figure out which screen you are on, by running this code (this is the windows form you are on)

Screen screen = Screen.FromControl(this); //this is the Form class

in short check out the Screen class and static helper methods, they might help you.

MSDN Link, doesn't have much..I suggest messing around in the code by yourself.

Solution 2

If you remember the window's location and size, that will be enough. When you set the position to the previously used position, if it happened to be on the second monitor it will go back there.

For example, if you have 2 monitors, both sized 1280x1024 and you set your window's left position to be 2000px, it will appear on the second monitor (assuming the second monitor is to the right of the first.) :)

If you are worried about the second monitor not being there when the application is started the next time, you can use this method to determine if your window intersects any of the screens:

private bool isWindowVisible(Rectangle rect)
{
    foreach (Screen screen in Screen.AllScreens)
    {
        if (screen.Bounds.IntersectsWith(rect))
            return true;
    }
    return false;
}

Just pass in your window's desired location and it will tell you if it will be visible on one of the screens. Enjoy!

Solution 3

You can get the current Screen with

var s = Screen.FromControl(this);

where this is the Form (or any control on the Form). As about how to remember that is a little tricky, but I would go for the index in the Screen.AllScreens array, or maybe s.DeviceName. In either case, check before using the settings on startup, to prevent using a monitor that was disconnected.

Share:
45,458
Stephen Fletcher
Author by

Stephen Fletcher

Updated on July 09, 2022

Comments

  • Stephen Fletcher
    Stephen Fletcher almost 2 years

    I have a C# Windows application that I want to ensure will show up on a second monitor if the user moves it to one. I need to save the main form's size, location and window state - which I've already handled - but I also need to know which screen it was on when the user closed the application.

    I'm using the Screen class to determine the size of the current screen but I can't find anything on how to determine which screen the application was running on.

    Edit: Thanks for the responses, everyone! I wanted to determine which monitor the window was on so I could do proper bounds checking in case the user accidentally put the window outside the viewing area or changed the screen size such that the form wouldn't be completely visible anymore.

  • Henk Holterman
    Henk Holterman almost 15 years
    agreed, but some checking at startup would be nice, so that after a reconfiguration your app won't be outside all all monitors
  • Powerlord
    Powerlord almost 15 years
    Yes, people seem to forget that Form inherits from Control, so Screen.FromControl would work on it.
  • Powerlord
    Powerlord almost 15 years
    Maybe I should rephrase that... Form inherits from ContainerControl, which inherits from ScrollableControl, which inherits from Control.
  • SolutionYogi
    SolutionYogi almost 15 years
    Actually, if someone removes the second monitor and your application will try to use Top/Left from the previous session when there were two monitors, Windows will automatically move it to the first monitor. So practically, you don't need to call isWindowVisible method.
  • Randy Stegbauer
    Randy Stegbauer almost 15 years
    I agree Henk - check the example I added so that you can check if your window will be visible. :)
  • Stan R.
    Stan R. almost 15 years
    i wouldn't go for the DeviceName, the DeviceName could change anytime, say when you get a new video card or monitor...
  • Henk Holterman
    Henk Holterman almost 15 years
    I get them as \\.\DISPLAY1 and \\.\DISPLAY2, on Vista. But it could be different for XP, I'm not sure.
  • Stan R.
    Stan R. almost 15 years
    I agree, nobody is really sure..which is why I wouldn't use it. :)
  • Stan R.
    Stan R. almost 15 years
    @Janie: I am sorry you feel this way. The code I provided, does exactly what I say it does. Nothing more, nothing less. If you want to research it more, please follow the MSDN link also provided.
  • Stan R.
    Stan R. almost 15 years
    @Janie: if you have a question with why it may not be working for you, then post it as a question and someone will surely help you out. I am sure it worked for the OP otherwise he would not have accepted the answer.
  • Tim
    Tim over 14 years
    @Janie: The FromControl() method returns a Screen object. Were you thinking it returns a screen number or something? You would need to query the Bounds of the Screen to determine the location of the screen.
  • neslekkiM
    neslekkiM over 10 years
    DisplayName seems to be just an generated value based on what Screen thinks is how the screens are. When using identify in the screenresolution dialog, you have totally different screen id's, same with say nvidia manager, it displays the same numbers as the screen resolution dialog, but .net absolutely have to do this different.
  • MCattle
    MCattle over 9 years
    Just a LINQy version for people using .NET 3.5 or later: return Screen.AllScreens.Any(s => s.Bounds.IntersectsWith(rect));
  • Jer Yango
    Jer Yango almost 5 years
    Make sure your external monitor is not set to Duplicate when running your app. Calling Screen.AllScreens.Length at this state will only return 1 (the primary screen only)