随着 .NET MAUI 9.0 的正式发布,跨平台应用开发迎来了又一次重大升级。众多开发者关注到,新版框架在 Windows 平台上增强了对原生窗口的自定义能力,其中“如何修改标题栏颜色”与“如何完全隐藏标题栏”成为社区讨论的热点。本文将为您详细解析 .NET MAUI 9.0 中实现这些功能的技术路径,并提供可直接运行的代码示例。

标题栏自定义:从“不可触碰”到“灵活掌控”

在之前的 .NET MAUI 版本中,Windows 应用的标题栏(TitleBar)几乎完全由操作系统控制:背景色默认跟随系统主题(浅色或深色),开发者只能通过修改 Window.Title 属性来改变显示文字。对于希望打造沉浸式界面(例如全屏阅读器、视频播放器或极简风格工具)的开发者而言,这种限制令人困扰。

.NET MAUI 9.0 通过引入更底层的 Window 互操作机制,打破了这一僵局。现在,您可以在不放弃 MAUI 跨平台优势的前提下,直接调用 WinUI 3 的 AppWindow API,从而对标题栏进行“手术级”自定义。

方法一:修改标题栏颜色

如果您的目标是让标题栏与应用的主色调保持一致,只需以下三步:

  1. 获取当前窗口的 AppWindow 实例
    App.xaml.cs 或页面代码中,通过 Microsoft.UI.Windowing.AppWindow.GetFromWindowHandle 方法获取。

  2. 设置标题栏颜色
    AppWindow 提供了 TitleBar 属性,其 BackgroundColorForegroundColorButtonBackgroundColor 等子属性均可单独调整。

  3. 要求框架允许自定义渲染
    必须将 TitleBar.ExtendsContentIntoTitleBar 设置为 true,否则系统会忽略颜色设置。

以下是一个完整的示例(Windows 平台特有代码需包裹在条件编译中):

#if WINDOWS
using Microsoft.UI.Windowing;
using Microsoft.UI;
using Windows.UI;
using WinRT.Interop;

// 在窗口创建后调用
void CustomizeTitleBar()
{
    var nativeWindow = (MauiWinUIWindow)App.Current.Windows[0].Handler.PlatformView;
    IntPtr windowHandle = WindowNative.GetWindowHandle(nativeWindow);
    WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
    var appWindow = AppWindow.GetFromWindowId(windowId);

    // 扩展内容到标题栏
    appWindow.TitleBar.ExtendsContentIntoTitleBar = true;

    // 设置背景色(深蓝)
    appWindow.TitleBar.BackgroundColor = Color.FromArgb(0, 50, 120);
    // 设置按钮悬浮背景色(浅蓝)
    appWindow.TitleBar.ButtonHoverBackgroundColor = Color.FromArgb(100, 150, 200);
    // 设置文字颜色为白色
    appWindow.TitleBar.ForegroundColor = Colors.White;
}
#endif

注意:当 ExtendsContentIntoTitleBartrue 时,系统会自动移除标题栏上的默认标题文本和图标,您需要在自定义区域手动添加这些元素。您可以使用 MAUI 的 Grid 布局接管顶部区域,实现完全自定义的标题栏 UI。

方法二:隐藏标题栏(实现全窗口沉浸式)

若您希望彻底隐藏标题栏,让应用窗口完全由内容占据(常见于游戏、媒体播放或 kiosk 模式),则需要将标题栏高度压缩为 0。这同样通过 AppWindow 实现:

#if WINDOWS
void HideTitleBar()
{
    var appWindow = GetAppWindow(); // 复用上面的获取逻辑
    appWindow.TitleBar.ExtendsContentIntoTitleBar = true;
    // 关键:将标题栏高度设为 0
    appWindow.TitleBar.Height = 0;
}
#endif

但请注意,仅设置 Height = 0 仍可能保留几像素的边框。更彻底的做法是同时修改窗口样式,移除非客户区。您可以使用 PInvoke 调用 SetWindowLong,设置 WS_CAPTIONWS_SYSMENU 等窗口样式为 0。这部分代码较为复杂,建议封装为 NuGet 包(如 MauiWindowTitleBar)以简化使用。

向后兼容与跨平台考量

需要强调的是,以上代码仅在 Windows 平台生效。若您的应用需同时支持 macOS、Android 或 iOS,必须在调用前使用条件编译指令 #if WINDOWS 保护,否则其他平台会因缺少对应 API 而编译失败。此外,macOS 平台可通过 NSWindowtitlebarAppearsTransparent 属性实现类似效果,Android 则需借助 WindowInsetsController

开发者社区反响与未来展望

自 .NET MAUI 9.0 预览版发布以来,GitHub 上关于标题栏自建的讨论帖已超过 200 条。多数开发者对此更新表示欢迎,认为它显著提升了 MAUI 在桌面端的可用性。但也有用户指出,当前 API 仍无法控制最小化、最大化、关闭按钮的单独颜色,且在某些高 DPI 缩放环境下会出现布局偏移。微软已在 .NET 9 路线图中承诺,将在后续迭代中完善这些细节。

结语

标题栏的自定义能力,是 .NET MAUI 从“移动优先”向“桌面优先”演进的关键一步。无论您是希望将标题栏融入品牌视觉,还是打造无边框的沉浸式体验,.NET MAUI 9.0 都提供了足够强大的底层支持。建议您在新项目中尽早尝试,并在社区分享您的实现方案——毕竟,更好的开发者生态,从来都来自主动探索与协同贡献。

相关资源
- 官方文档:AppWindow.TitleBar
- 示例项目:dotnet/maui-samples (TitleBarCustomization)
- 讨论区:github.com/dotnet/maui/discussions