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

使用SingleBorderWindow和WindowChrome的WPF全屏应用超屏问题

解决WPF自定义窗口工具栏的动画与多显示器适配冲突问题

要同时保留系统窗口状态切换/最小化动画,又解决多显示器下最大化时的右侧1像素溢出问题,不需要切换WindowStyle,可以通过以下方案实现:

核心思路

保留WindowStyle.SingleBorderWindow以获取原生系统动画,通过调整WindowChrome参数隐藏默认标题栏,同时在窗口最大化时动态修正窗口边距,抵消溢出问题。

修改后的实现代码

XAML代码

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStyle="SingleBorderWindow"
        StateChanged="MainWindow_OnStateChanged">
    <!-- 此处添加你的自定义工具栏和页面内容 -->
</Window>

C#代码

using System.Windows;
using System.Windows.Shell;

namespace WpfTest
{
    public partial class MainWindow : Window
    {
        private Thickness _originalMargin;

        public MainWindow()
        {
            InitializeComponent();
            _originalMargin = Margin;
            
            var chrome = new WindowChrome
            {
                CaptionHeight = 0, // 隐藏系统默认标题栏
                ResizeBorderThickness = new Thickness(8), // 保证窗口拖拽缩放功能正常
                GlassFrameThickness = new Thickness(0), // 禁用玻璃效果避免干扰自定义布局
                UseAeroCaptionButtons = false // 关闭系统自带的最小化/最大化/关闭按钮
            };
            WindowChrome.SetWindowChrome(this, chrome);
        }

        private void MainWindow_OnStateChanged(object sender, EventArgs e)
        {
            if (WindowState == WindowState.Maximized)
            {
                // 获取当前窗口所在的屏幕区域
                var screen = System.Windows.Forms.Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(this).Handle);
                var workingArea = screen.WorkingArea;
                // 动态调整边距,抵消多显示器下的溢出问题
                Margin = new Thickness(
                    Left - workingArea.Left,
                    Top - workingArea.Top,
                    workingArea.Right - Right,
                    workingArea.Bottom - Bottom
                );
            }
            else
            {
                // 窗口恢复正常状态时还原原边距
                Margin = _originalMargin;
            }
        }
    }
}

关键说明

  1. 保留系统动画:始终使用WindowStyle.SingleBorderWindow,原生的窗口状态切换、最小化动画会正常生效。
  2. 隐藏默认标题栏:通过WindowChrome.CaptionHeight = 0和UseAeroCaptionButtons = false完全隐藏系统默认标题栏及按钮,为自定义工具栏腾出空间。
  3. 修正最大化溢出:在StateChanged事件中,根据当前屏幕的工作区域动态调整窗口边距,确保最大化时完全贴合屏幕边界,不会溢出到其他显示器。
  4. 原方案失效原因:之前切换WindowStyle的时机太晚,窗口已经完成最大化布局,修改WindowStyle无法触发重新计算布局,因此溢出问题无法解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:07:32