Определение того, полностью ли закрыта форма - PullRequest
35 голосов
/ 12 июня 2009

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

Я надеялся сделать эту проверку в обработчике события Form_Shown. По сути, я хочу определить, находится ли форма полностью за пределами экрана, чтобы я мог ее переместить.

Любой совет?

Ответы [ 7 ]

57 голосов
/ 12 июня 2009

Проверьте с помощью этой функции, если форма полностью на экране :

public bool IsOnScreen( Form form )
{
   Screen[] screens = Screen.AllScreens;
   foreach( Screen screen in screens )
   {
      Rectangle formRectangle = new Rectangle( form.Left, form.Top, 
                                               form.Width, form.Height );

      if( screen.WorkingArea.Contains( formRectangle ) )
      {
         return true;
      }
   }

   return false;
}

Проверка только левая верхняя точка , если она на экране:

public bool IsOnScreen( Form form )
{
   Screen[] screens = Screen.AllScreens;
   foreach( Screen screen in screens )
   {
      Point formTopLeft = new Point( form.Left, form.Top );

      if( screen.WorkingArea.Contains( formTopLeft ) )
      {
         return true;
      }
   }

   return false;
}
15 голосов
/ 25 июля 2012

Объединение всех описанных выше решений с методом «IntersectsWith» и расширениями LINQ дает нам вкратце:

public bool IsOnScreen(Form form) 
{
   // Create rectangle
   Rectangle formRectangle = new Rectangle(form.Left, form.Top, form.Width, form.Height); 

   // Test
   return Screen.AllScreens.Any(s => s.WorkingArea.IntersectsWith(formRectangle));
}
9 голосов
/ 13 апреля 2015

Полное решение здесь (на основе всех ответов). Я добавил параметр MinPercentOnScreen, где хотя бы этот% пикселей должен быть виден на всех экранах / дисплеях. Поэтому, если это возвращает false, вам нужно переместить положение окна обратно к значению по умолчанию.

// Return True if a certain percent of a rectangle is shown across the total screen area of all monitors, otherwise return False.
public bool IsOnScreen(System.Drawing.Point RecLocation, System.Drawing.Size RecSize, double MinPercentOnScreen = 0.2)
{
    double PixelsVisible = 0;
    System.Drawing.Rectangle Rec = new System.Drawing.Rectangle(RecLocation, RecSize);

    foreach (Screen Scrn in Screen.AllScreens)
    {
        System.Drawing.Rectangle r = System.Drawing.Rectangle.Intersect(Rec, Scrn.WorkingArea);
        // intersect rectangle with screen
        if (r.Width != 0 & r.Height != 0)
        {
            PixelsVisible += (r.Width * r.Height);
            // tally visible pixels
        }
    }
    return PixelsVisible >= (Rec.Width * Rec.Height) * MinPercentOnScreen;
}

Реализация:

return IsOnScreen(this.Location, this.Size);
4 голосов
/ 17 декабря 2010

Старая тема, но все же полезно! Коди и Андрия - спасибо за код. Мне пришлось внести пару небольших корректировок: Вместо screen.WorkingArea.Intersect (formRectangle); Я использовал formRectangle.Intersect (screen.WorkingArea); поскольку Intersect () заменяет свой объект пересечением. Если форма полностью за пределами экрана, formRectangle после пересечения равен (0,0,0,0), и Contains () возвращает true. Поэтому я также проверяю, все ли значения FormRectangle Top, Left, Width и Height равны 0, прежде чем возвращать true Теперь код возвращает true, если какая-либо часть формы находится на экране, и false, если на экране нет какой-либо части.

1 голос
/ 05 июня 2013

Для WPF (на основе ответа Матиаса Леркеса)

Добавить ссылку на System.Windows.Forms и System.Drawing .

//using System.Windows.Forms;

public bool IsOnScreen(Window window)
{
   var windowRect = new System.Drawing.Rectangle((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height);
   return Screen.AllScreens.Any(s => s.WorkingArea.IntersectsWith(windowRect));
}
0 голосов
/ 14 апреля 2019

Ничего из этого не работает, если монитор выключен. Функция Screen.AllScreens всегда возвращает количество экранов, даже если один из них выключен.

0 голосов
/ 12 июня 2009

Проверьте разрешение экрана, прежде чем расположить окно. Это позволит вам выяснить, хотите ли вы разместить его за пределами разрешения, прежде чем вы действительно это сделаете.

...