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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/987018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:57:35  来源:igfitidea点击:

Determining if a form is completely off screen

c#winformsscreen

提问by Cody

I am developing an application that remembers the user's preferences as to where the form was last located on the screen. In some instances the user will have it on a secondary screen, and then fire the app up later without the second screen (sometimes having the form appear off screen). Other times the user will change their resolution resulting in a similar effect.

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

I was hoping to do this checking in the Form_Shown event handler. Basically I want to determine whether the form is completely off screen so I can re-position it.

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

Any advice?

有什么建议吗?

采纳答案by Andrija

Check with this function if Form is fully on screen:

如果 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;
}

Checking only top left pointif it's on screen:

如果它在屏幕上,检查左上角

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

回答by Allen Rice

Check the screens resolution before you position the window. That will allow you to figure out if you where going to place it outside the bounds of the resolution, before you actually do it.

在定位窗口之前检查屏幕分辨率。这将使您能够在实际操作之前弄清楚是否要将其放置在分辨率范围之外。

回答by Sean

Old thread, but still helpful! Cody and Andrija- thanks for the code. I had to make a couple of minor adjustments: Instead of screen.WorkingArea.Intersect(formRectangle); I used formRectangle.Intersect(screen.WorkingArea); since Intersect() replaces its object with the intersection. If the form is completely off the screen, formRectangle after the intersection is (0,0,0,0), and Contains() returns true. So I also check to see if formRectangle Top, Left, Width and Height are not all 0 before returning true. Now the code returns true if any part of the form is on screen, and false if no part is on screen.

旧线程,但仍然有用!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。

回答by Matthias Loerke

Combining all the solutions above with the "IntersectsWith"-method and LINQ-extensions give us in short:

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

回答by salle55

For WPF(based on Matthias Loerkes answer)

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

Add a reference to System.Windows.Formsand System.Drawing.

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

回答by CrazyTim

Complete solution here (based on all answers). I have added a parameter MinPercentOnScreenwhere at least this % of pixels must be visible across all screens/displays. So if this returns falseyou will need to move the window's position back to default.

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

Implementation:

执行:

return IsOnScreen(this.Location, this.Size);

回答by Tom

None of these work if a monitor happens to be off. The Screen.AllScreens function will always return the number of screens even if one is off.

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