WPF最大化时全屏显示

11

我想要当按下F11键或者在窗口右上角按下最大化按钮时,我的WPF窗口可以进入全屏模式。

虽然下面的代码可以实现按下F11键时的功能:

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.F11)
    {
        WindowStyle = WindowStyle.None;
        WindowState = WindowState.Maximized;
        ResizeMode = ResizeMode.NoResize;
    }
}

这段代码仍然会显示Windows任务栏(已在Windows 7上测试):

protected override void OnStateChanged(EventArgs e)
{
    if (WindowState == WindowState.Maximized)
    {
        WindowStyle = WindowStyle.None;
        WindowState = WindowState.Maximized;
        ResizeMode = ResizeMode.NoResize;
    }
    base.OnStateChanged(e);
}

我在这里错过了什么?或者我能更加优雅地完成它吗?

9个回答

22

根据WindowStyle的设置,WPF似乎会决定是进入全屏模式还是尊重任务栏。因此,一种笨拙但有效的解决方案是将窗口切换回非最大化状态,设置WindowStyle,然后再将窗口最大化:

private bool _inStateChange;

protected override void OnStateChanged(EventArgs e)
{
  if (WindowState == WindowState.Maximized && !_inStateChange)
  {
    _inStateChange = true;
    WindowState = WindowState.Normal;
    WindowStyle = WindowStyle.None;
    WindowState = WindowState.Maximized;
    ResizeMode = ResizeMode.NoResize;
    _inStateChange = false;
  }
  base.OnStateChanged(e);
}

虽然这段代码显然很丑陋,但从正常状态到最大化状态再返回,似乎并不会影响用户体验。在我的显示器上,我发现F11代码和临时最大化都有闪烁,但在临时最大化情况下没有明显更糟的情况。但具体效果因人而异!


5
"叩叩"声——谁在门外?——来自70年代的信号灯。虽然是老货,但它还能用。+1 - Filip Ekberg
这个代码可以很好地工作。即使它看起来很丑,但对于像全屏这样基本的功能来说,它仍然比实现WindowInteropHelper或某些dll导入要好得多。我必须考虑一下,总的来说是个不错的想法! - Martin Buberl
1
实际上,这会在Windows XP中产生一个丑陋的可见效果,因为WindowState的两个更改在Windows XP中具有视觉表示,即蓝色标题栏上下移动,使用此技术会使窗口看起来像是醉酒了。 - cprcrack

4

试试这个

Topmost="True" and WindowState="Maximized"

您会发现,您的窗口将覆盖整个屏幕并隐藏所有的Windows任务栏。


在Windows 10上(周年更新版),比其他任何软件都表现得更好! - James Esh

3

我尝试了另一种解决方案:

你可以在构造函数中设置该窗口的MaxHeight属性为SystemParameters.MaximizedPrimaryScreenHeight。

public MainWindow()
{
    InitializeComponent();
    this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
}

警告:这可能在扩展桌面上无法正常工作。

来源: 最大化窗口的WindowState问题(应用程序将隐藏Windows任务栏)


3

我尝试使用 Topmost = true; 但它并不会改变行为。 - Martin Buberl
愚蠢的问题。我该如何检查我的任务栏是否设置为“最顶层”?正如我所说,按F11键时它可以正常工作(无论是否使用Topmost)。 - Martin Buberl
好问题,似乎在Windows 7中无法更改。我会进行更多测试并回复您。 - Filip Ekberg
谢谢,我会非常感激的。这种行为让我疯狂 ;) - Martin Buberl
这对我不起作用 - 奇怪的是,它剪辑了任务栏的一部分,但没有整个任务栏(带有Aero主题的Server 2008)。 - itowlson
@itowlson:这也是我在Windows 7上遇到的问题。此外,如果Aero主题有任何重要性的话。 - Martin Buberl

2
如果您正在使用WindowChrome创建自定义的浏览器体验,您需要将GlassFrameThickness设置为非0值(至少这是我最后需要做的事情,以使任务栏隐藏在窗口后面)。这是除了接受的答案提供的步骤之外的额外步骤。

1
在我的情况下,最小化和最大化将使全屏大小比屏幕略大一些,因此我找到的替代方法是暂时将可见性设置为Collapsed,然后再切换回Visible以强制重新绘制。
Visibility = Visibility.Collapsed;
WindowStyle = WindowStyle.None;
WindowState = WindowState.Maximized;
ResizeMode = ResizeMode.NoResize;
Visibility = Visibility.Visible;

1
如果仍有人需要在Windows 10上测试的平滑全屏,那么请保持这个代码顺序!在Windows 10最小化时,闪烁会减少。
    public bool IsFullscreen = false;
    public WindowState lastWindowState;
    private void player_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (IsFullscreen)
        {
            this.WindowStyle = WindowStyle.SingleBorderWindow;
            this.WindowState = lastWindowState;
            IsFullscreen = false;

        }
        else
        {
            lastWindowState = this.WindowState;

            this.WindowStyle = WindowStyle.None;
            if (this.WindowState == WindowState.Maximized)
                this.WindowState = WindowState.Minimized;
            this.WindowState = WindowState.Maximized;
            IsFullscreen = true;
        }
    }

谢谢,它在 Windows XP 和 Windows 7 上也运行得很好。 - dbostream
这个答案的问题在于它使用了MouseDoubleClick事件,而问题是如何改变最大化按钮的行为。虽然这样做可以解决问题,但如果在此示例中使用的事件被更改以便解决问题,那么效果会更好。 - 絢瀬絵里

0

如果您导入user32.dll,就可以隐藏任务栏...

[DllImport("user32.dll")]
private static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);

private const int SW_HIDE = 0;
private const int SW_SHOW = 1;

使用方法:

int hwnd = FindWindow("Shell_TrayWnd","");
ShowWindow(hwnd,SW_HIDE);

5
你刚刚摧毁了我的任务栏! - Filip Ekberg
谢谢kzen!不管怎样,这对我来说似乎不太像WPF风格。但这可能是一个选项。 - Martin Buberl
它实际上只是移除了我的任务栏中所有的图标,而没有移除任务栏本身。 - Filip Ekberg

0
我已经找到了在WPF中实现全屏的简单方法:
    private double LastHeight, LastWidth;
    private System.Windows.WindowState LastState;

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.F11)
        {
            if (WindowStyle != WindowStyle.None)
            {
                LastHeight = Height;
                LastWidth = Width;
                LastState = WindowState;

                Topmost = true;
                Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
                Top = 0;
                Left = 0;
                WindowState = System.Windows.WindowState.Normal;
                WindowStyle = WindowStyle.None;
                ResizeMode = System.Windows.ResizeMode.NoResize;
            }
            else
            {
                WindowStyle = WindowStyle.SingleBorderWindow;
                WindowState = LastState; ;
                ResizeMode = ResizeMode.CanResizeWithGrip;
                Topmost = false;
                Width = LastWidth;
                Height = LastHeight;
            }
        }
    }

这在 Windows 7 上与固定任务栏很好用。


当您在双屏幕机器上运行程序时,这种方式不起作用,因为程序始终最大化显示在左侧屏幕上。 - André

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