C# 显示带有 WPF、Winforms 和双显示器的窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/512398/
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-04 06:17:55  来源:igfitidea点击:

Showing a window with WPF, Winforms, and Dual monitors

c#wpfwinformsmultiple-monitors

提问by NotDan

I have a 2 monitors and a WinForm app that launches a WPF window. I want to get the screen that the WinForm is on, and show the WPF window on the same screen. How can I do this?

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

采纳答案by Adrian

WPF doesn't include the handy System.Windows.Forms.Screenclass, but you can still use its properties to accomplish your task in your WinForms application.

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

Assume that thismeans the WinForms window and _wpfWindowis a defined variable referencing the WPF Window in the example below (this would be in whatever code handler you set to open the WPF Window, like some Button.Click handler):

假设意味着 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();

The above code will instantiate the WPF Window at the Top-Left corner of the screen containing your WinForms Window. I'll leave the math to you if you wish to place it in another location like the middle of the screen or in a "cascading" style below and to the right of your WinForms Window.

上面的代码将在包含 WinForms 窗口的屏幕左上角实例化 WPF 窗口。如果您希望将其放置在另一个位置,例如屏幕中间或 WinForms 窗口下方和右侧的“级联”样式,我会将数学留给您。

Another method that gets the WPF Window in the middle of the screen would be to simply use

在屏幕中间获取 WPF 窗口的另一种方法是简单地使用

_wpfWIndow.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen

However, this isn't quite as flexible because it uses the position of the mouse to figure out which screen to display the WPF Window (and obviously the mouse could be on a different screen as your WinForms app if the user moves it quickly, or you use a default button, or whatever).

但是,这不是很灵活,因为它使用鼠标的位置来确定显示 WPF 窗口的屏幕(如果用户快速移动鼠标,显然鼠标可能与 WinForms 应用程序位于不同的屏幕上,或者您使用默认按钮,或其他)。

Edit: Here's a link to an SDK documentabout using InterOp to get your WPF Window centered over the non-WPF Window. It does basically what I was describing in terms of figuring out the math, but correctly allows you to set the WPF Window's "Owner" property using the Window's HWND.

编辑:这是关于使用 InterOp 使 WPF 窗口居中于非 WPF 窗口的 SDK 文档的链接。它基本上完成了我在计算数学方面所描述的内容,但正确地允许您使用窗口的 HWND 设置 WPF 窗口的“所有者”属性。

回答by Dominic Hopton

You should be able to use System.Windows.Forms.Screen [1], and use the FromControl method to get the screen info for the form. You can then use this for positioning the WPF window (top, left) based on the screen you are trying to locate it on.

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

[1] You can also use the win32 MonitorFromRect et al, if you don't to load the WinForms dlls. However, since you've already got the winforms API, you're not going to pay any memory/perf hit.

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

回答by Simon Brangwin

Here's the simplest way (uses WindowStartupLocation.CenterOwner).

这是最简单的方法(使用 WindowStartupLocation.CenterOwner)。

MyDialogWindow dialogWindow = new MyDialogWindow();
dialogWindow.Owner = this;
dialogWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;

dialogWindow.ShowDialog();

No need for interop or setting window coords :)

不需要互操作或设置窗口坐标:)

回答by Joben Blom

Another way of doing it is:

另一种方法是:

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;

this = your WPF Window...

这 = 您的 WPF 窗口...