Как определить, на каком мониторе работает моя программа .NET Windows Forms?

У меня есть приложение C # для Windows, которое, как я хочу, будет отображаться на втором мониторе, если пользователь переместит его на один. Мне нужно сохранить размер, расположение и состояние окна основной формы - с чем я уже работал - но мне также нужно знать, на каком экране она находилась, когда пользователь закрыл приложение.

Я использую класс Screen для определения размера текущего экрана, но я не могу найти ничего о том, как определить, на каком экране было запущено приложение.

Изменить: Всем спасибо за ответы! Я хотел определить, на каком мониторе находится окно, чтобы я мог правильно проверить границы на случай, если пользователь случайно поместил окно за пределы области просмотра или изменил размер экрана, чтобы форма больше не была полностью видимой.


person Stephen Fletcher    schedule 13.07.2009    source источник
comment
Если это не вопрос, похожий на stackoverflow.com/questions/937298/   -  person sgmoore    schedule 13.07.2009


Ответы (5)


Вы можете получить массив экранов, которые у вас есть, используя этот код.

Screen[] screens = Screen.AllScreens;

Вы также можете определить, на каком экране вы находитесь, запустив этот код (это форма окна, в которой вы находитесь).

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

вкратце ознакомьтесь с классом Screen и статическими вспомогательными методами, они могут вам помочь.

Ссылка MSDN не имеет большого количества. .Я предлагаю самому повозиться с кодом.

person Stan R.    schedule 13.07.2009
comment
Да, люди, кажется, забывают, что Form наследуется от Control, поэтому Screen.FromControl будет работать с этим. - person Powerlord; 13.07.2009
comment
Может быть, мне стоит перефразировать это ... Форма наследуется от ContainerControl, который наследуется от ScrollableControl, который наследуется от Control. - person Powerlord; 13.07.2009
comment
@Janie: Мне жаль, что ты так себя чувствуешь. Код, который я предоставил, делает именно то, что я говорю. Ни больше ни меньше. Если вы хотите узнать больше, перейдите по также предоставленной ссылке MSDN. - person Stan R.; 14.07.2009
comment
@Janie: если у вас есть вопрос, почему он может не работать для вас, опубликуйте его как вопрос, и кто-нибудь обязательно вам поможет. Я уверен, что это сработало для OP, иначе он бы не принял ответ. - person Stan R.; 14.07.2009
comment
@Janie: Метод FromControl () возвращает объект Screen. Вы думали, что он возвращает номер экрана или что-то в этом роде? Вам нужно будет запросить границы экрана, чтобы определить местоположение экрана. - person Tim; 22.02.2010
comment
Убедитесь, что внешний монитор не установлен на Duplicate при запуске приложения. Вызов Screen.AllScreens.Length в этом состоянии вернет только 1 (только основной экран) - person Jer Yango; 03.09.2019

Если вы запомните расположение и размер окна, этого будет достаточно. Когда вы устанавливаете положение в ранее использованное положение, если оно было на втором мониторе, оно вернется туда.

Например, если у вас есть 2 монитора, оба размером 1280x1024, и вы установили левое положение окна на 2000 пикселей, оно появится на втором мониторе (при условии, что второй монитор находится справа от первого.) :)

Если вас беспокоит, что второй монитор не будет там, когда приложение будет запущено в следующий раз, вы можете использовать этот метод, чтобы определить, пересекает ли ваше окно какой-либо из экранов:

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

Просто пройдите в желаемое место вашего окна, и оно скажет вам, будет ли оно видно на одном из экранов. Наслаждаться!

person Jon Tackabury    schedule 13.07.2009
comment
согласен, но некоторая проверка при запуске была бы неплохой, чтобы после перенастройки ваше приложение не выходило за пределы всех мониторов - person Henk Holterman; 13.07.2009
comment
Фактически, если кто-то удалит второй монитор, и ваше приложение попытается использовать Top / Left из предыдущего сеанса, когда было два монитора, Windows автоматически переместит его на первый монитор. Таким образом, практически вам не нужно вызывать метод isWindowVisible. - person SolutionYogi; 13.07.2009
comment
Я согласен, Хенк - проверьте пример, который я добавил, чтобы вы могли проверить, будет ли ваше окно видимым. :) - person Jon Tackabury; 13.07.2009
comment
Просто версия LINQy для людей, использующих .NET 3.5 или новее: return Screen.AllScreens.Any(s => s.Bounds.IntersectsWith(rect)); - person MCattle; 28.11.2014

Вы можете получить текущий экран с помощью

var s = Screen.FromControl(this);

где this - это форма (или любой элемент управления в форме). Что касается того, как запомнить, это немного сложно, но я бы выбрал индекс в массиве Screen.AllScreens или, может быть, s.DeviceName. В любом случае проверьте перед использованием настроек при запуске, чтобы предотвратить использование монитора, который был отключен.

person Henk Holterman    schedule 13.07.2009
comment
Я бы не стал использовать DeviceName, DeviceName может измениться в любое время, скажем, когда вы получите новую видеокарту или монитор ... - person Stan R.; 14.07.2009
comment
Я получаю их как \\. \ DISPLAY1 и \\. \ DISPLAY2 в Vista. Но для XP все могло быть иначе, не уверен. - person Henk Holterman; 14.07.2009
comment
Я согласен, никто не уверен ... поэтому я бы не стал его использовать. :) - person Stan R.; 14.07.2009
comment
DisplayName кажется просто сгенерированным значением, основанным на том, что Screen думает о том, как выглядят экраны. При использовании идентификации в диалоговом окне разрешения экрана у вас есть совершенно разные идентификаторы экрана, такие же, как, скажем, диспетчер nvidia, он отображает те же числа, что и диалоговое окно разрешения экрана, но .net абсолютно должен делать это по-другому. - person neslekkiM; 03.12.2013

Расположение формы подскажет, на каком экране она находится. Я действительно не понимаю, почему вам нужно знать, на каком экране он находится, потому что, если вы восстановите его, используя сохраненное место, оно должно просто восстановиться в том же месте (возможно, вы можете объяснить, почему).

В противном случае вы можете сделать что-то вроде этого:

Screen[] scr = Screen.AllScreens;
scr[i].Bounds.IntersectsWith(form.Bounds);

Каждый экран имеет свойство Bounds, которое возвращает прямоугольник. Вы можете использовать функцию IntersectsWith (), чтобы определить, находится ли форма на экране.

Кроме того, они в основном предоставляют функцию, которая делает это также в классе Screen.

Screen screen = Screen.FromControl(form);
person Chap    schedule 13.07.2009

Вы можете использовать объект «Экран»: System.Windows.Forms.Screen

Начните играть примерно так:

        Screen[] screens = Screen.AllScreens;
        for (int i = 0; i < screens.Length ; i++)
        {
            Debug.Print(screens[i].Bounds.ToString());
            Debug.Print(screens[i].DeviceName);
            Debug.Print(screens[i].WorkingArea.ToString());
        }

Это может дать вам то, что вам нужно

person Community    schedule 13.07.2009