Определение того, полностью ли сформирована форма

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

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

Любые советы?

Ответ 1

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

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

Ответ 2

Объединяя все вышеизложенные решения с помощью метода "Интерсекции с помощью" и 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));
}

Ответ 3

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

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

Ответ 5

Для 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));
}

Ответ 6

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

Ответ 7

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