显示带有WPF,Winforms和双显示器的窗口

我有一个2监视器和一个启动WPF窗口的WinForm应用程序。 我想获得WinForm所在的屏幕,并在同一屏幕上显示WPF窗口。 我怎样才能做到这一点?

WPF不包括方便的System.Windows.Forms。 Screen类,但您仍然可以使用其属性在WinForms应用程序中完成任务。

假设意味着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应用程序的不同屏幕上,或者你使用默认按钮,或其他)。

编辑: 这是一个SDK文档的链接,该文档关于使用InterOp将WPF窗口置于非WPF窗口的中心。 它基本上是我在描述数学时所描述的,但正确地允许你使用Window的HWND设置WPF窗口的“Owner”属性。

这是最简单的方法(使用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窗口……

您应该能够使用System.Windows.Forms.Screen [1],并使用FromControl方法获取表单的屏幕信息。 然后,您可以根据您尝试定位的屏幕使用它来定位WPF窗口(顶部,左侧)。

[1]如果你不加载WinForms dll,你也可以使用win32 MonitorFromRect等。 但是,由于您已经获得了winforms API,因此您不会支付任何内存/性能。