47

我正在开发一个应用程序,它可以记住用户对表单最后在屏幕上的位置的偏好。在某些情况下,用户会将它放在第二个屏幕上,然后稍后在没有第二个屏幕的情况下启动应用程序(有时表单会出现在屏幕外)。其他时候,用户会改变他们的分辨率,从而产生类似的效果。

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

有什么建议吗?

4

7 回答 7

69

如果 Form完全显示在屏幕上,请使用此功能检查:

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;
}
于 2009-06-12T14:56:52.870 回答
20

将上述所有解决方案与“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));
}
于 2012-07-25T17:45:40.213 回答
10

此处的完整解决方案(基于所有答案)。我添加了一个参数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);
于 2015-04-13T00:52:24.243 回答
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。

于 2010-12-16T22:08:22.497 回答
1

对于WPF(基于 Matthias Loerkes 的回答)

添加对System.Windows.FormsSystem.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));
}
于 2013-06-04T22:05:20.310 回答
1

如果显示器碰巧关闭,这些都不起作用。Screen.AllScreens 函数将始终返回屏幕数,即使一个屏幕关闭。

于 2019-04-14T19:03:23.527 回答
0

在定位窗口之前检查屏幕分辨率。这将允许您在实际执行之前确定是否将其放置在分辨率范围之外。

于 2009-06-12T14:57:51.043 回答