You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

WPF:不改WindowStyle等属性前提下移除最大化窗口边框?

解决WPF最大化无标题窗口的边框问题(保留原有属性)

我完全懂你的困境——既要保留WindowState="Maximized"WindowStyle="None"AllowsTransparency="False"ResizeMode="CanResize"这些属性,又要去掉窗口周围的边框,还得保证PdfViewer、WebBrowser这类控件正常工作。下面几个方案应该能帮到你:

方案1:使用WPF原生WindowChrome(推荐)

WindowChrome是WPF提供的原生窗口定制工具,不用开启透明就能自定义窗口框架,完美适配你的需求。你只需要给窗口添加WindowChrome配置,把玻璃边框厚度设为0,同时保留可调整大小的边框区域:

修改后的XAML代码:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle="None"
        WindowState="Maximized"
        AllowsTransparency="False"
        ResizeMode="CanResize"
        UseLayoutRounding="True"
        Title="MainWindow">
    <!-- 添加WindowChrome配置 -->
    <Window.WindowChrome>
        <WindowChrome GlassFrameThickness="0" 
                      ResizeBorderThickness="5" />
        <!-- ResizeBorderThickness设置为5,保证用户能拖动边缘调整窗口大小 -->
    </Window.WindowChrome>
    <Grid Background="Red"></Grid>
</Window>

这个方案的好处是完全基于WPF原生API,不需要写复杂的后台代码,而且不会影响任何控件的正常显示,同时完美保留你要求的所有窗口属性。

方案2:手动调整窗口大小适配工作区

如果方案1还是有细微边框,可能是DPI缩放导致WPF的最大化计算出现偏差。你可以在窗口加载时手动把窗口大小设置为屏幕工作区的尺寸(自动排除任务栏):

首先在XAML中添加Loaded事件:

<Window x:Class="WpfApplication8.MainWindow"
        ...
        Loaded="Window_Loaded">
    <Grid Background="Red"></Grid>
</Window>

然后在后台代码中实现事件逻辑:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // 获取屏幕工作区(自动排除任务栏)
    var workingArea = System.Windows.SystemParameters.WorkArea;
    // 手动设置窗口位置和大小
    this.Left = workingArea.Left;
    this.Top = workingArea.Top;
    this.Width = workingArea.Width;
    this.Height = workingArea.Height;
}

这个方法通过强制窗口铺满工作区,消除因系统计算误差产生的边框,同时保留所有原有属性。

方案3:调用Win32 API修改窗口样式

如果上面两个方案都不生效,你可以直接修改Windows原生窗口的扩展样式,去掉导致边框的WS_EX_CLIENTEDGE属性:

后台代码实现:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

public partial class MainWindow : Window
{
    private const int GWL_EXSTYLE = -20;
    private const int WS_EX_CLIENTEDGE = 0x00000200;

    [DllImport("user32.dll")]
    private static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    private static extern int SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        var hwnd = new WindowInteropHelper(this).Handle;
        // 获取当前窗口扩展样式
        int exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
        // 去掉WS_EX_CLIENTEDGE样式
        exStyle &= ~WS_EX_CLIENTEDGE;
        // 应用新样式
        SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle);
        // 刷新窗口使更改生效
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, 0x0001 | 0x0002 | 0x0004);
    }
}

这个方法直接操作Windows底层窗口样式,能彻底消除边框,同时保留窗口的可调整大小功能,也不会影响控件显示。

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

火山引擎 最新活动