我正在开发一个应用程序,它可以记住用户对表单最后在屏幕上的位置的偏好。在某些情况下,用户会将它放在第二个屏幕上,然后稍后在没有第二个屏幕的情况下启动应用程序(有时表单会出现在屏幕外)。其他时候,用户会改变他们的分辨率,从而产生类似的效果。
我希望在 Form_Shown 事件处理程序中进行此检查。基本上我想确定表单是否完全不在屏幕上,以便重新定位它。
有什么建议吗?
如果 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;
}
将上述所有解决方案与“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));
}
此处的完整解决方案(基于所有答案)。我添加了一个参数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 和 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。
对于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));
}
如果显示器碰巧关闭,这些都不起作用。Screen.AllScreens 函数将始终返回屏幕数,即使一个屏幕关闭。
在定位窗口之前检查屏幕分辨率。这将允许您在实际执行之前确定是否将其放置在分辨率范围之外。