【发布时间】:2010-10-05 11:20:38
【问题描述】:
我有 2 个监视器和一个启动 WPF 窗口的 WinForm 应用程序。我想获取 WinForm 所在的屏幕,并在同一屏幕上显示 WPF 窗口。我该怎么做?
【问题讨论】:
标签: c# wpf winforms multiple-monitors
我有 2 个监视器和一个启动 WPF 窗口的 WinForm 应用程序。我想获取 WinForm 所在的屏幕,并在同一屏幕上显示 WPF 窗口。我该怎么做?
【问题讨论】:
标签: c# wpf winforms multiple-monitors
WPF 不包含方便的 System.Windows.Forms.Screen 类,但您仍然可以使用它的属性在 WinForms 应用程序中完成任务。
假设 this 表示 WinForms 窗口,并且 _wpfWindow 是在下面的示例中引用 WPF 窗口的已定义变量(这将在您设置为打开的任何代码处理程序中WPF 窗口,就像一些 Button.Click 处理程序):
Screen screen = Screen.FromControl(this);
_wpfWindow.StartupLocation = System.Windows.WindowStartupLocation.Manual;
_wpfWindow.Top = screen.Bounds.Top;
_wpfWindow.Left = screen.Bounds.Left;
_wpfWindow.Show();
上面的代码将在包含 WinForms 窗口的屏幕左上角实例化 WPF 窗口。如果您希望将其放置在另一个位置,例如屏幕中间,或者以“层叠”样式放置在 WinForms 窗口的下方和右侧,我会留给您计算。
另一种让 WPF 窗口位于屏幕中间的方法是简单地使用
_wpfWIndow.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen
但是,这不是很灵活,因为它使用鼠标的位置来确定显示 WPF 窗口的屏幕(显然,如果用户移动鼠标,鼠标可能与 WinForms 应用程序位于不同的屏幕上快速,或者您使用默认按钮,或其他)。
编辑:Here's a link to an SDK document 关于使用 InterOp 使您的 WPF 窗口居中于非 WPF 窗口。它基本上完成了我在计算数学方面所描述的内容,但正确地允许您使用窗口的 HWND 设置 WPF 窗口的“所有者”属性。
【讨论】:
您应该能够使用 System.Windows.Forms.Screen [1],并使用 FromControl 方法获取表单的屏幕信息。然后,您可以使用它根据您尝试定位的屏幕来定位 WPF 窗口(顶部,左侧)。
[1] 如果您不加载 WinForms dll,您也可以使用 win32 MonitorFromRect 等。但是,由于您已经获得了 winforms API,因此您无需支付任何内存/性能损失。
【讨论】:
这是最简单的方法(使用 WindowStartupLocation.CenterOwner)。
MyDialogWindow dialogWindow = new MyDialogWindow();
dialogWindow.Owner = this;
dialogWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
dialogWindow.ShowDialog();
无需互操作或设置窗口坐标 :)
【讨论】:
另一种方法是:
WindowInteropHelper helper = new WindowInteropHelper(this);
this.StartupLocation = System.Windows.WindowStartupLocation.Manual;
this.Left = System.Windows.Forms.Screen.FromHandle(helper.Handle).Bounds.Left;
this.Top = System.Windows.Forms.Screen.FromHandle(helper.Handle).Bounds.Top;
这 = 你的 WPF 窗口...
【讨论】: