在第二个显示器上全屏显示

28

如何在dotNet Windows(或WPF)应用程序中编程,以使其在副显示器上全屏显示?

8个回答

38

拓展方法:将窗口最大化到第二个显示器(如果有的话)。 不假设第二个显示器是 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;
            }
        }
    }
}

16

针对WPF应用程序,请查看这篇文章。最终取决于何时将WindowState设置为Maximized。如果您在XAML或窗口构造函数中设置它(即在窗口加载之前),它将始终最大化到主显示器上。另一方面,如果您在窗口加载时将WindowState设置为Maximized,则它将最大化到先前最大化的屏幕上。


谢谢!将恢复位置代码从窗口类构造函数移动到_Loaded_处理程序中有所帮助。我唯一需要补充的是,Window类在发送_Loaded_通知之前以默认设置发送_LocationChanged_通知,因此您应该跳过_LocationChanged_通知,直到在_Loaded_处理程序中恢复窗口位置。 - Mar
比顶部投票好得多 - 它实际上可以像真正的全屏一样摆脱标题栏。 - Gabe Halsmer

11

我注意到有一个答案建议在Loaded事件中设置位置,但是当窗口首次显示正常然后最大化时,这会导致闪烁。如果你在构造函数中订阅SourceInitialized事件并在其中设置位置,它将处理在二级监视器上最大化而不会出现闪烁 - 我假设这里使用的是WPF。

public MyWindow()
{
    SourceInitialized += MyWindow_SourceInitialized;
}

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

将coords替换为您的第二个显示器上的任何坐标


只有这个答案对我有帮助。 - saidfagan
这个答案对我来说也是最好的。 - Jan Van Overbeke

8

5
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;
}

这个可以工作,但需要引用 System.Windows.Forms.dll。 - Rick Rat

1

@jay-evans的回答对我很有帮助。但是,我还需要添加WpfscreenHelper Nuget包以获取屏幕信息,而不依赖于旧的System.Windows.Forms命名空间,就像@grantnz的回答一样。

还要注意的是,仅设置尺寸(左、上、宽度+高度)会在每个边缘留下一个小边框。只有在设置WindowState.Maximized后,才能实现真正的全屏效果。

由于我的显示器具有不同的DPI配置,因此我还必须使用WpfWorkingArea而不是WorkingArea,因为坐标返回不正确。

为了完整起见,在这里发布,这是使用WPF和.NET 7.0,并已确认可与不同的DPI配置一起使用:

    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;
        }
    }

0

从你的问题中并不清楚你是想要将窗口移动到辅助显示器然后全屏,还是只是想在窗口所在的任何显示器上(可能是主显示器或辅助显示器)支持全屏模式。

如果是后者,对于 WPF 窗口,虽然不完全等同于全屏模式,但可以在最大化时删除边框,在非最大化时恢复边框。无需检查哪个显示器等等。标题栏的显示由边框状态控制。

    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);
    }

感谢Pavel在当前问题中给出的基于表单的答案,以及Nir在this question问题中的回答。


-1
在WPF中:将WindowState属性设置为Normal(而不是Maximized),并创建Loaded事件。在事件中编写以下代码:
this.Left = SystemParameters.PrimaryScreenWidth + 100;
this.WindowState = System.Windows.WindowState.Maximized;

4
这假设辅助显示器在主显示器的右侧。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接