views:

4701

answers:

3

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?

+5  A: 

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

Assume that this means the WinForms window and _wpfWindow is 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):

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.

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

_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).

Edit: Here's a link to an SDK document about 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.

KP Adrian
+1  A: 

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.

[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.

dhopton
+2  A: 

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

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

dialogWindow.ShowDialog();

No need for interop or setting window coords :)

Simon Brangwin