Monday, January 14, 2008

Maximizing a WPF Window to second monitor

I'm trying to develop and application that utilizes a maximized window on the second monitor.

There's a few issues here. The first is that WPF doesn't offer the same information as WinForms about monitor configuration. WinForms has SystemInformation.MonitorCount and Screen.AllScreens[i].WorkingArea. WPF has SystemParameters.PrimaryScreen[Width/Height] and SystemParameters.VirtualScreen[Width/Height] which almost works (as long as you don't have more than two monitors) but not really. So back to using WinForms API...

Secondly, the obvious solution to display a form maximized on second screen was to me the following:

                fullScreenWindow.WindowStartupLocation = WindowStartupLocation.Manual;

Debug.Assert(System.Windows.Forms.SystemInformation.MonitorCount > 1);

System.Drawing.Rectangle workingArea = System.Windows.Forms.Screen.AllScreens[1].WorkingArea;
fullScreenWindow.Left = workingArea.Left;
fullScreenWindow.Top = workingArea.Top;
fullScreenWindow.Width = workingArea.Width;
fullScreenWindow.Height = workingArea.Height;
fullScreenWindow.WindowState = WindowState.Maximized;
fullScreenWindow.WindowStyle = WindowStyle.None;
fullScreenWindow.Topmost = true;
fullScreenWindow.Show();

However, when you try that you'll end up with a topmost maximized window on your primary display, which was not what we wanted.


Turns out that we cannot maximize the window until it's loaded. So by hooking the Loaded event of fullScreenWindow and handling the event along the lines of:

        private void Window_Loaded(object sender, RoutedEventArgs e) {
WindowState = WindowState.Maximized;
}

...it works.


Oh, and you want to make certain that you are running a dual monitor configuration so you do not put the window somewhere where it is off-screen.

10 comments:

Anonymous said...

Thank you. Great stuff. :o)

Anonymous said...

Spent about a hour trying to figure out why the fullscreen window wouldn't display on the secondary monitor - your tip about maximizing in the Loaded event saved me from pulling out the rest of my hair!

Botz3000 said...

Thanks! That's just what i looked for!

Anonymous said...

Worked perfectly - THANKS!

Anonymous said...

really Thanks!
baz

Anonymous said...

thank you! why on earth does it position on the primary monitor unless you maximise in the loaded event?? sometimes WPF seems quite pants!

Anonymous said...

Where do I put the first code?

Anonymous said...

Thank you very much!

Aybe said...

By showing the window first, you can avoid maximizing it in its Loaded event.

MainWindow.Show();

// Try to position application to first non-primary monitor
if (Screen.AllScreens.Length >= 2)
{
var secondary = 0;
for (int index = 0; index < Screen.AllScreens.Length; index++)
{
if (Screen.AllScreens[index].Primary) continue;
secondary = index;
break;
}

var screen = Screen.AllScreens[secondary];
if (screen != null)
{
var area = screen.WorkingArea;
if (!area.IsEmpty)
{
MainWindow.Left = area.Left;
MainWindow.Top = area.Top;
MainWindow.Width = area.Width;
MainWindow.Height = area.Height;
MainWindow.WindowState = WindowState.Maximized;
}
}
}

Thank you !

Anonymous said...

Great help thanks.
Also works without flickering in Window_SourceInitialized event :-)