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

如何在WPF C#中实现标题栏对系统明暗模式的适配?

WPF 原生标题栏明暗模式适配方案

问题说明

我想对我的WPF应用做少量自定义,打算保留原生标题栏,不做自定义标题栏改造。但遇到的问题是:即便Windows系统已经设置为暗色模式,WPF应用的标题栏仍然显示为亮色模式,我没有找到合适的指导教程来实现标题栏对明暗两种模式的适配。
StackOverflow上的多数回答都建议通过样式自定义标题栏及按钮等所有控件,但我不确定这是不是最优方案。
有没有人知道如何将WPF标题栏切换为暗色模式,以及如何切回亮色模式?我当前使用的技术栈是.NET 5 + WPF + C# :)
默认亮色模式标题栏截图
我已将Windows设置为暗色模式(Hell = 亮色,Dunkel = 暗色)
Windows11主题设置截图

问题补充

尝试过使用WindowChrome的方案但遇到报错:插入WindowChrome的样式Setter属性时,收到报错提示“System.Windows.Shell”命名空间下不存在“WindowChrome”属性,Setter.Value部分也报相同错误。
尝试使用的代码:

<Setter Property="shell:WindowChrome">
    <Setter.Value>
        <shell:WindowChrome />
    </Setter.Value>
</Setter>

尝试引入的命名空间:

xmlns:shell="System.Windows.Shell"                
xmlns:shell1="http://schemas.microsoft.com/expression/blend/2008"               
xmlns:shell2="http://schemas.microsoft.com/netfx/2009/xaml/presentation"

解决方案

1. 先解决WindowChrome报错问题

.NET 5 版本的WPF已经将WindowChrome集成到PresentationFramework程序集中,命名空间引用方式变更,正确的XAML引用语法为:

xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"

如果你不想自定义标题栏,完全不需要使用WindowChrome,直接调用Windows系统API修改原生标题栏属性即可,所有原生交互逻辑都会保留,无需额外适配。

2. 调用DWM API修改原生标题栏明暗模式

该方案支持Windows 10 1809及以上版本,不需要修改任何标题栏样式,最大化最小化按钮、拖拽、系统右键菜单、Windows11 snap布局功能都完全保留。

步骤1:导入API和常量

在窗口的后台C#代码中添加如下内容:

using System.Runtime.InteropServices;
using System.Windows.Interop;
// 适配不同Windows版本的暗色模式属性标识
private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;

[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);

步骤2:编写标题栏模式切换方法

private bool SetTitleBarMode(bool isDarkMode)
{
    IntPtr windowHandle = new WindowInteropHelper(this).Handle;
    if (windowHandle == IntPtr.Zero) return false;

    int attributeValue = isDarkMode ? 1 : 0;
    int attributeId = Environment.OSVersion.Version.Build >= 19041 
        ? DWMWA_USE_IMMERSIVE_DARK_MODE 
        : DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;

    return DwmSetWindowAttribute(windowHandle, attributeId, ref attributeValue, sizeof(int)) == 0;
}

步骤3:调用方法切换模式

在窗口初始化完成后调用,例如在SourceInitialized事件中触发:

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    // 开启暗色标题栏,传false则切换为亮色
    SetTitleBarMode(true);
}

如果需要跟随系统主题自动切换,可以注册Microsoft.Win32.SystemEvents.UserPreferenceChanged事件,监听系统主题变更后调用上述方法即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:45:08