如何确定我的 .NET Windows Forms 程序在哪个监视器上运行?
Posted
技术标签:
【中文标题】如何确定我的 .NET Windows Forms 程序在哪个监视器上运行?【英文标题】:How do I determine which monitor my .NET Windows Forms program is running on? 【发布时间】:2010-11-10 10:22:48 【问题描述】:我有一个 C# Windows 应用程序,我想确保如果用户将其移至第二台显示器,它会显示在第二台显示器上。我需要保存主窗体的大小、位置和窗口状态——我已经处理过了——但我还需要知道用户关闭应用程序时它在哪个屏幕上。
我正在使用 Screen 类来确定当前屏幕的大小,但我找不到任何关于如何确定应用程序在哪个屏幕上运行的信息。
编辑:感谢大家的回复!我想确定窗口在哪个监视器上,这样我就可以进行适当的边界检查,以防用户不小心将窗口放在查看区域之外或更改了屏幕大小,从而使表单不再完全可见。
【问题讨论】:
如果这不是与***.com/questions/937298/…类似的问题 【参考方案1】:如果您记住窗口的位置和大小,那就足够了。当您将位置设置为之前使用的位置时,如果它恰好在第二台显示器上,它将回到那里。
例如,如果您有 2 台显示器,尺寸均为 1280x1024,并且您将窗口的左侧位置设置为 2000 像素,则它将出现在第二台显示器上(假设第二台显示器在第一台显示器的右侧。):)
如果您担心下次启动应用程序时第二个监视器不在,您可以使用此方法来确定您的窗口是否与任何屏幕相交:
private bool isWindowVisible(Rectangle rect)
foreach (Screen screen in Screen.AllScreens)
if (screen.Bounds.IntersectsWith(rect))
return true;
return false;
只需传入您窗口的所需位置,它就会告诉您它是否会在其中一个屏幕上可见。享受吧!
【讨论】:
同意,但是在启动时进行一些检查会很好,这样在重新配置后您的应用就不会出现在所有监视器之外 实际上,如果有人移除了第二个监视器,并且当有两个监视器时,您的应用程序将尝试使用上一个会话中的 Top/Left,Windows 会自动将其移动到第一个监视器。所以实际上,你不需要调用 isWindowVisible 方法。 我同意 Henk - 检查我添加的示例,以便您可以检查您的窗口是否可见。 :) 只是一个 LINQy 版本,供使用 .NET 3.5 或更高版本的人使用:return Screen.AllScreens.Any(s => s.Bounds.IntersectsWith(rect));
【参考方案2】:
您可以使用“屏幕”对象: System.Windows.Forms.Screen
开始玩这样的东西:
Screen[] screens = Screen.AllScreens;
for (int i = 0; i < screens.Length ; i++)
Debug.Print(screens[i].Bounds.ToString());
Debug.Print(screens[i].DeviceName);
Debug.Print(screens[i].WorkingArea.ToString());
它可能会为您提供所需的东西
【讨论】:
【参考方案3】:您可以使用此代码获取您拥有的一组屏幕。
Screen[] screens = Screen.AllScreens;
您还可以通过运行此代码来确定您在哪个屏幕上(这个是您所在的窗口)
Screen screen = Screen.FromControl(this); //this is the Form class
简而言之,请查看 Screen 类和静态辅助方法,它们可能会对您有所帮助。
MSDN Link, 没有太多..我建议你自己乱搞代码。
【讨论】:
是的,人们似乎忘记了 Form 继承自 Control,所以 Screen.FromControl 可以处理它。 也许我应该重新表述一下... Form 继承自 ContainerControl,ContainerControl 继承自 ScrollableControl,后者继承自 Control。 @Janie:很抱歉你有这种感觉。我提供的代码完全符合我所说的。不多也不少。如果您想进一步研究它,请按照同时提供的 MSDN 链接进行操作。 @Janie:如果您对为什么它可能不适合您有疑问,请将其作为问题发布,一定会有人帮助您。我确信它对 OP 有效,否则他不会接受答案。 @Janie:FromControl() 方法返回一个 Screen 对象。您是否认为它会返回屏幕编号或其他内容?您需要查询屏幕的边界以确定屏幕的位置。【参考方案4】:您可以通过
获取当前屏幕var s = Screen.FromControl(this);
其中this
是表单(或表单上的任何控件)。至于如何记住这有点棘手,但我会选择 Screen.AllScreens 数组中的索引,或者可能是 s.DeviceName。无论哪种情况,请在启动时使用设置之前进行检查,以防止使用已断开连接的显示器。
【讨论】:
我不会选择 DeviceName,DeviceName 可以随时更改,比如当您获得新的视频卡或显示器时... 我在 Vista 上将它们设为 \\.\DISPLAY1 和 \\.\DISPLAY2。但对于 XP,它可能会有所不同,我不确定。 我同意,没有人真正确定..这就是我不使用它的原因。 :) DisplayName 似乎只是根据 Screen 认为屏幕的样子生成的值。在屏幕分辨率对话框中使用识别时,您有完全不同的屏幕 ID,与说 nvidia 管理器相同,它显示与屏幕分辨率对话框相同的数字,但 .net 绝对必须这样做不同。【参考方案5】:表单的位置会告诉您表单在哪个屏幕上。我真的不明白为什么您需要知道它在哪个屏幕上,因为如果您使用保存的位置恢复它,它应该只恢复到相同的位置(也许您可以详细说明原因)。
否则你可以这样做:
Screen[] scr = Screen.AllScreens;
scr[i].Bounds.IntersectsWith(form.Bounds);
每个屏幕都有一个 Bounds 属性,它返回一个 Rectangle。您可以使用 IntersectsWith() 函数来确定表单是否在屏幕内。
此外,它们基本上提供了一个在 Screen 类上也能做到这一点的函数
Screen screen = Screen.FromControl(form);
【讨论】:
以上是关于如何确定我的 .NET Windows Forms 程序在哪个监视器上运行?的主要内容,如果未能解决你的问题,请参考以下文章
.net Windows Forms 应用程序的自动 CRUD 表单生成
如何清除 System.Windows.Forms.WebBrowser 会话数据?
用不了System.Windows.Forms,如何使用MessageBox?