You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF设置WindowState=WindowState.Maximized时窗口无法正确最大化问题

pic

问题根因

  • XAML中ResizeMode属性拼写错误,正确值为NoResize,拼写错误会导致属性不生效,干扰窗口状态计算
  • 当WindowStyle="None"且AllowsTransparency="True"时,WPF默认的最大化逻辑不会自动适配系统工作区(即排除任务栏的屏幕可用区域),同时默认最大化会自带不可见的外边距,导致窗口看起来未铺满屏幕
  • 未手动处理最大化时的窗口尺寸边界,系统默认逻辑对无边框透明窗口的适配存在缺陷

解决方案

方案1:重写窗口消息处理(推荐)

该方案无需修改原有最大化调用逻辑,设置WindowState = WindowState.Maximized即可正常生效。

  1. 首先修正XAML中的拼写错误:
<!-- 将错误的ResizeMode="NoResiz"改为 -->
ResizeMode="NoResize"
  1. 在窗口的后台代码中添加如下逻辑,处理系统最大化尺寸计算消息:
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

// 你的窗口类
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        var hwnd = new WindowInteropHelper(this).Handle;
        HwndSource.FromHwnd(hwnd).AddHook(WndProc);
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        // 拦截最大化尺寸查询消息
        if (msg == 0x0024 /* WM_GETMINMAXINFO */)
        {
            MINMAXINFO mmi = Marshal.PtrToStructure<MINMAXINFO>(lParam);
            // 适配系统工作区(自动排除任务栏、工具栏等系统占用区域)
            var workingArea = SystemParameters.WorkArea;
            mmi.ptMaxPosition.X = (int)workingArea.Left;
            mmi.ptMaxPosition.Y = (int)workingArea.Top;
            mmi.ptMaxSize.X = (int)workingArea.Width;
            mmi.ptMaxSize.Y = (int)workingArea.Height;
            Marshal.StructureToPtr(mmi, lParam, true);
            handled = true;
        }
        return IntPtr.Zero;
    }

    // 定义Win32所需结构体
    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int X;
        public int Y;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MINMAXINFO
    {
        public POINT ptReserved;
        public POINT ptMaxSize;
        public POINT ptMaxPosition;
        public POINT ptMinTrackSize;
        public POINT ptMaxTrackSize;
    }
}

方案2:手动控制窗口最大化

如果不想使用Win32API,可以不依赖WindowState.Maximized,手动设置窗口位置和尺寸实现最大化:

// 定义私有字段记录窗口状态
private bool _isMaximized = false;
private double _normalLeft, _normalTop, _normalWidth, _normalHeight;

// 最大化切换方法
private void ToggleMaximize()
{
    if (!_isMaximized)
    {
        // 保存正常状态下的窗口尺寸位置
        _normalLeft = Left;
        _normalTop = Top;
        _normalWidth = Width;
        _normalHeight = Height;
        // 适配工作区
        var workingArea = SystemParameters.WorkArea;
        Left = workingArea.Left;
        Top = workingArea.Top;
        Width = workingArea.Width;
        Height = workingArea.Height;
        _isMaximized = true;
    }
    else
    {
        // 还原到正常状态
        Left = _normalLeft;
        Top = _normalTop;
        Width = _normalWidth;
        Height = _normalHeight;
        _isMaximized = false;
    }
}

注意事项

  • 上述方案均支持系统DPI缩放,无需额外适配
  • 如果你不需要窗口透明效果,可以将AllowsTransparency设为False,配合WindowChrome类自定义无边框窗口,系统适配性更好

内容的提问来源于stack exchange,提问作者skillgamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:21:03