2009-06-12 46 views
29

我正在开发一个应用程序,它记录了用户对表单最后位于屏幕上的位置的偏好。在某些情况下,用户将会在第二个屏幕上显示它,然后在没有第二个屏幕的情况下启动应用程序(有时会将屏幕显示在屏幕外)。其他时候,用户将改变他们的分辨率,导致类似的效果。确定一个表单是否完全不在屏幕上

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

有什么建议吗?

+0

我要指出,我知道我可以通过获取表单的屏幕分辨率,大小和位置进行一些棘手的逻辑,但我希望的东西有点更优雅。 – Cody 2009-06-12 14:50:53

+0

你真的认为它更加优雅地定位表单,检查它是否在分辨率/大小之外,然后重新定位它?一个更优雅的解决方案将是检查,看看你是否要在你做之前把它放在屏幕上。 – 2009-08-28 18:57:47

回答

49

检查使用此功能,如果表是完全在屏幕上

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

我忘了如何以其他方式获得Form矩形,但我希望这有助于 – 2009-06-12 14:58:10

+0

看起来非常整齐,我不知道该功能是否存在。一个问题,但:如果窗口只是部分屏幕外,这不会仍然返回false?这个问题要求完全在屏幕外。 – 2009-06-12 14:59:50

0

你的位置前,请检查屏幕分辨率窗户。这将使您能够确定在实际执行操作之前,是否将其置于解决方案的界限之外。

3

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

12

结合上面的 “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)); 
} 
1

对于WPF(基于马蒂亚斯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)); 
} 
8

完整的解决方案在这里(根据所有答案)。我添加了一个参数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); 
相关问题