【发布时间】:2010-10-19 16:58:43
【问题描述】:
如何对 dotNet Windows(或 WPF)应用程序进行编程以使其在辅助监视器上全屏显示?
【问题讨论】:
标签: .net wpf windows fullscreen multiple-monitors
如何对 dotNet Windows(或 WPF)应用程序进行编程以使其在辅助监视器上全屏显示?
【问题讨论】:
标签: .net wpf windows fullscreen multiple-monitors
将窗口最大化到辅助监视器(如果有的话)的扩展方法。 不假定辅助监视器是 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 应用程序,请查看 this post。最终它取决于 WindowState 何时设置为最大化。如果您在 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;
}
在辅助显示器上替换任何坐标
【讨论】:
其中的代码可以使用,但默认为您的主显示器。要更改这一点,您需要替换对 GetSystemMetrics 的调用将调用 GetMonitorInfo。使用 GetMonitorInfo,您可以获得适当的 RECT 以传递给 SetWindowPos。
GetMonitorInfo 允许您获取任何监视器的 RECT。
有一个MSDN Article on Position Apps in Multi-Monitor Setups 可能有助于更好地解释事情。
【讨论】:
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;
}
【讨论】:
如果您正在寻找一种将窗口移动到辅助监视器然后进入全屏的方法,或者您只是希望在窗口所在的任何监视器上支持全屏模式(可能是主要或次要)。
如果是后者,对于 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 中的回答。
【讨论】:
在 WPF 中:将 WindowState 属性设置为 Normal(不是 Maximixed)并创建事件 Loaded。在事件中编写此代码:
this.Left = SystemParameters.PrimaryScreenWidth + 100;
this.WindowState = System.Windows.WindowState.Maximized;
【讨论】: