user91295
user91295

Reputation: 306

Going fullscreen on secondary monitor

How can you program a dotNet Windows (or WPF) Application in order to let it going fullscreen on the secondary monitor?

Upvotes: 28

Views: 32618

Answers (8)

Joerg
Joerg

Reputation: 237

@jay-evans answer did the trick for me. However, I also needed to add the WpfscreenHelper Nuget package to get the screen information while not depending on the old System.Windows.Forms namespace as in @grantnz's answer.

Also note that setting the dimensions only (left, top, width + height) left me with a small border on each side. Only after setting WindowState.Maximized is it that the real full-screen effect was achieved.

Since I have monitors with varying DPI configurations, I also had to use WpfWorkingArea instead of WorkingArea, since the coordinates were coming back incorrectly.

Posting here for completeness, this is using WPF with .NET 7.0 and is confirmed to work with varying DPI configurations:

    public MainWindow()
    {
        InitializeComponent();
        SourceInitialized += MainWindow_SourceInitialized;
    }

    private void MainWindow_SourceInitialized(object? sender, EventArgs e)
    {
        var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(s => !s.Primary);
        if (screen != null)
        {
            this.WindowState = WindowState.Normal;
            this.Left = screen.WpfWorkingArea.Left;
            this.Top = screen.WpfWorkingArea.Top;
            this.Width = screen.WpfWorkingArea.Width;
            this.Height = screen.WpfWorkingArea.Height;
            this.WindowState = WindowState.Maximized;
        }
    }

Upvotes: 1

Jay Evans
Jay Evans

Reputation: 255

I notice an answer which advocates setting the position in the Loaded event, but this causes flicker when the window is first shown normal then maximized. If you subscribe to the SourceInitialized event in your constructor and set the position in there it will handle maximizing onto secondary monitors without flicker - I'm assuming WPF here

public MyWindow()
{
    SourceInitialized += MyWindow_SourceInitialized;
}

void MyWindow_SourceInitialized(object sender, EventArgs e)
{
    Left = 100;
    Top = 50;
    Width = 800;
    Height = 600;
    WindowState = WindowState.Maximized;
}

Substitute coords for any on your secondary monitor

Upvotes: 12

grantnz
grantnz

Reputation: 7423

Extension method to Maximize a window to the secondary monitor (if there is one). Doesn't assume that the secondary monitor is System.Windows.Forms.Screen.AllScreens[2];

using System.Linq;
using System.Windows;

namespace ExtendedControls
{
    static public class WindowExt
    {

        // NB : Best to call this function from the windows Loaded event or after showing the window
        // (otherwise window is just positioned to fill the secondary monitor rather than being maximised).
        public static void MaximizeToSecondaryMonitor(this Window window)
        {
            var secondaryScreen = System.Windows.Forms.Screen.AllScreens.Where(s => !s.Primary).FirstOrDefault();

            if (secondaryScreen != null)
            {
                if (!window.IsLoaded)
                    window.WindowStartupLocation = WindowStartupLocation.Manual;

                var workingArea = secondaryScreen.WorkingArea;
                window.Left = workingArea.Left;
                window.Top = workingArea.Top;
                window.Width = workingArea.Width;
                window.Height = workingArea.Height;
                // If window isn't loaded then maxmizing will result in the window displaying on the primary monitor
                if ( window.IsLoaded )
                    window.WindowState = WindowState.Maximized;
            }
        }
    }
}

Upvotes: 38

Juan Carlos Velez
Juan Carlos Velez

Reputation: 2940

In WPF: Set the WindowState property in Normal (not Maximixed) and create the event Loaded. In the event write this code:

this.Left = SystemParameters.PrimaryScreenWidth + 100;
this.WindowState = System.Windows.WindowState.Maximized;

Upvotes: -1

Alex_P
Alex_P

Reputation: 1896

For WPF apps look at this post. Ultimately it depends on when the WindowState is set to Maximized. If you set it in XAML or in window constructor (i.e. before the window is loaded) it will always be maximized onto primary display. If, on the other hand, you set WindowState to Maximized when the window is loaded - it will maximise on the screen on which it was maximized before.

Upvotes: 16

sean e
sean e

Reputation: 11925

It's not clear from your question if you are looking for a way to move the window to the secondary monitor and then go fullscreen, or if you are just looking to support fullscreen mode on whatever monitor the window is on (which may be primary or secondary).

If the later, for a WPF window, though not quite the same as fullscreen mode, you can remove the borders when it is maximized and restore the border when not maximized. No need to check for which monitor, etc. The display of the caption/title bar is controlled by the border state.

    protected override void OnStateChanged(EventArgs e)
    {
        if (WindowState == WindowState.Maximized)
        {
            if (WindowStyle.None != WindowStyle)
                WindowStyle = WindowStyle.None;
        }
        else if (WindowStyle != WindowStyle.SingleBorderWindow)
            WindowStyle = WindowStyle.SingleBorderWindow;

        base.OnStateChanged(e);
    }

Credit goes to Pavel for his Forms-based answer in the current question and to Nir for his answer in this question.

Upvotes: 0

Pavel Chuchuva
Pavel Chuchuva

Reputation: 22465

private void Form1_Load(object sender, EventArgs e)
{
   this.FormBorderStyle = FormBorderStyle.None;
   this.Bounds = GetSecondaryScreen().Bounds;
}

private Screen GetSecondaryScreen()
{
   foreach (Screen screen in Screen.AllScreens)
   {
      if (screen != Screen.PrimaryScreen)
         return screen;
   }
   return Screen.PrimaryScreen;
}

Upvotes: 5

Reed Copsey
Reed Copsey

Reputation: 564451

See this codeproject article.

The code in there will work, but default to your primary monitor. To change this, you'll need to replace the calls to GetSystemMetrics will calls to GetMonitorInfo. Using GetMonitorInfo, you can get the appropriate RECT to pass to SetWindowPos.

GetMonitorInfo allows you to get the RECT for any monitor.

There is an MSDN Article on Position Apps in Multi-Monitor Setups that might help explain things a bit better.

Upvotes: 8

Related Questions