.NET MAUI Windows应用移除默认标题栏及自定义实现问题
.NET MAUI Windows 自定义标题栏解决方案
一、修复SetWindowLong代码问题
你当前直接设置WS_POPUP样式会覆盖窗口原有必要样式,导致窗口布局异常(截断问题)。正确做法是保留原有窗口样式,仅移除标题栏相关的标志位,同时强制窗口刷新布局以适配无标题栏状态:
// 定义Win32 API常量和方法 const int GWL_STYLE = -16; const int WS_CAPTION = 0x00C00000; const int WS_THICKFRAME = 0x00040000; const int SWP_NOMOVE = 0x0002; const int SWP_NOSIZE = 0x0001; const int SWP_FRAMECHANGED = 0x0020; [DllImport("user32.dll")] static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); // 修改映射代码 WindowHandler.Mapper.AppendToMapping("CustomFunc", (handler, view) => { var nativeWindow = handler.PlatformView; IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow); // 获取当前样式,移除标题栏(如需保留可调边框,只去掉WS_CAPTION即可) int currentStyle = GetWindowLong(hWnd, GWL_STYLE); int newStyle = currentStyle & ~WS_CAPTION & ~WS_THICKFRAME; SetWindowLong(hWnd, GWL_STYLE, newStyle); // 强制窗口刷新布局,解决截断问题 SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); nativeWindow.Activate(); });
二、使用MAUI原生特性实现(推荐)
完全不需要依赖Win32 API,MAUI在Windows平台提供了原生的标题栏自定义能力,布局更稳定:
1. 隐藏默认标题栏并延伸内容到标题栏区域
在App.xaml.cs的窗口初始化方法中配置:
protected override Window CreateWindow(IActivationState activationState) { var window = new Window(new MainPage()); #if WINDOWS // 让页面内容延伸到标题栏区域 window.ExtendsContentIntoTitleBar = true; // 隐藏默认标题栏的系统按钮(最小化、最大化、关闭) var platformWindow = window.Handler.PlatformView as Microsoft.UI.Xaml.Window; platformWindow.TitleBar.IsVisible = false; #endif return window; }
2. 设置自定义标题栏内容
在页面XAML中添加自定义标题栏布局:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourApp.MainPage"> <Grid> <!-- 自定义标题栏 --> <Grid x:Name="CustomTitleBar" HeightRequest="48" BackgroundColor="#2C3E50"> <Label Text="我的自定义标题" TextColor="White" VerticalOptions="Center" Margin="16,0"/> <Button Text="返回" TextColor="White" BackgroundColor="Transparent" HorizontalOptions="End" Margin="0,0,16,0"/> </Grid> <!-- 页面主体内容 --> <ScrollView Grid.Row="1"> <!-- 你的页面内容 --> </ScrollView> </Grid> </ContentPage>
在页面代码后台绑定标题栏:
protected override void OnHandlerChanged() { base.OnHandlerChanged(); #if WINDOWS // 将自定义布局设置为窗口标题栏 Window.SetTitleBar(CustomTitleBar); #endif }
内容的提问来源于stack exchange,提问作者Pierpaolo
相关产品推荐
相关产品推荐

