确定表单是否完全脱离屏幕

时间:2009-06-12 14:45:30

标签: c# winforms screen

我正在开发一个应用程序来记住用户关于表单最后位于屏幕上的位置的首选项。在某些情况下,用户将其放在辅助屏幕上,然后在没有第二个屏幕的情况下稍后启动应用程序(有时窗体显示在屏幕外)。其他时候,用户将更改其分辨率,从而产生类似的效果。

我希望在Form_Shown事件处理程序中执行此检查。基本上我想确定表格是否完全不在屏幕上,所以我可以重新定位它。

有什么建议吗?

7 个答案:

答案 0 :(得分:57)

如果表格完全在屏幕上

,请检查此功能
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;
}

答案 1 :(得分:15)

将上述所有解决方案与“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));
}

答案 2 :(得分:9)

此处完整解决方案(基于所有答案)。我添加了一个参数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);

答案 3 :(得分:4)

旧线程,但仍然有帮助! Cody和Andrija-感谢代码。我不得不做一些小的调整: 而不是screen.WorkingArea.Intersect(formRectangle);我用了formRectangle.Intersect(screen.WorkingArea);因为Intersect()用交集替换它的对象。如果表单完全不在屏幕上,则交集后的formRectangle为(0,0,0,0),而Contains()返回true。所以我还要检查formRectangle Top,Left,Width和Height在返回true之前是否都不是0。现在,如果表单的任何部分在屏幕上,则代码返回true,如果屏幕上没有任何部分,则返回false。

答案 4 :(得分:1)

对于 WPF (基于Matthias Loerkes回答)

添加对 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));
}

答案 5 :(得分:0)

在放置窗口之前检查屏幕分辨率。这样你就可以在实际操作之前弄清楚你是否将它放在分辨率的范围之外。

答案 6 :(得分:0)

如果显示器恰好关闭,这些工作均无效。即使关闭一个屏幕,Screen.AllScreens函数也将始终返回屏幕数。