我正在开发一个应用程序,它记录了用户对表单最后位于屏幕上的位置的偏好。在某些情况下,用户将会在第二个屏幕上显示它,然后在没有第二个屏幕的情况下启动应用程序(有时会将屏幕显示在屏幕外)。其他时候,用户将改变他们的分辨率,导致类似的效果。确定一个表单是否完全不在屏幕上
我希望能够在Form_Shown事件处理程序中执行此检查。基本上我想确定表单是否完全在屏幕外,以便我可以重新定位它。
有什么建议吗?
我正在开发一个应用程序,它记录了用户对表单最后位于屏幕上的位置的偏好。在某些情况下,用户将会在第二个屏幕上显示它,然后在没有第二个屏幕的情况下启动应用程序(有时会将屏幕显示在屏幕外)。其他时候,用户将改变他们的分辨率,导致类似的效果。确定一个表单是否完全不在屏幕上
我希望能够在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;
}
我忘了如何以其他方式获得Form矩形,但我希望这有助于 – 2009-06-12 14:58:10
看起来非常整齐,我不知道该功能是否存在。一个问题,但:如果窗口只是部分屏幕外,这不会仍然返回false?这个问题要求完全在屏幕外。 – 2009-06-12 14:59:50
你的位置前,请检查屏幕分辨率窗户。这将使您能够确定在实际执行操作之前,是否将其置于解决方案的界限之外。
旧的线程,但仍然有帮助! 科迪和安德里亚 - 感谢您的代码。我不得不做一些小的调整: 而不是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。
结合上面的 “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));
}
对于WPF(基于马蒂亚斯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));
}
完整的解决方案在这里(根据所有答案)。我添加了一个参数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);
我要指出,我知道我可以通过获取表单的屏幕分辨率,大小和位置进行一些棘手的逻辑,但我希望的东西有点更优雅。 – Cody 2009-06-12 14:50:53
你真的认为它更加优雅地定位表单,检查它是否在分辨率/大小之外,然后重新定位它?一个更优雅的解决方案将是检查,看看你是否要在你做之前把它放在屏幕上。 – 2009-08-28 18:57:47