如何在dotNet Windows(或WPF)应用程序中编程,以使其在副显示器上全屏显示?
如何在dotNet Windows(或WPF)应用程序中编程,以使其在副显示器上全屏显示?
拓展方法:将窗口最大化到第二个显示器(如果有的话)。 不假设第二个显示器是 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;
}
}
}
}
针对WPF应用程序,请查看这篇文章。最终取决于何时将WindowState设置为Maximized。如果您在XAML或窗口构造函数中设置它(即在窗口加载之前),它将始终最大化到主显示器上。另一方面,如果您在窗口加载时将WindowState设置为Maximized,则它将最大化到先前最大化的屏幕上。
我注意到有一个答案建议在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替换为您的第二个显示器上的任何坐标
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;
}
@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;
}
}
从你的问题中并不清楚你是想要将窗口移动到辅助显示器然后全屏,还是只是想在窗口所在的任何显示器上(可能是主显示器或辅助显示器)支持全屏模式。
如果是后者,对于 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问题中的回答。
this.Left = SystemParameters.PrimaryScreenWidth + 100;
this.WindowState = System.Windows.WindowState.Maximized;