Определение того, находится ли форма полностью за пределами экрана

StackOverflow https://stackoverflow.com/questions/987018

  •  13-09-2019
  •  | 
  •  

Вопрос

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

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

Любой совет?

Это было полезно?

Решение

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

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;
}

Другие советы

Объединение всех приведенных выше решений с методом «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));
}

Полное решение здесь (на основе всех ответов).Я добавил параметр 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);

Старая тема, но все равно полезная!Коди и Андрия, спасибо за код.Пришлось внести пару небольших корректировок:Вместо 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, если на экране нет ни одной части.

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

Добавьте ссылку на Система.Windows.Forms и Система.Рисование.

//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));
}

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top