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

WinUI应用全屏模式下如何实现类似UWP的标题栏访问?

实现WinUI中类似UWP的沉浸式全屏模式

要实现鼠标悬停顶部显示标题栏的全屏效果,不能直接使用AppWindowPresenterKind.FullScreen(该模式为独占全屏,会完全隐藏标题栏),需要通过自定义窗口尺寸+控制标题栏可见性模拟UWP的沉浸式全屏行为,具体实现如下:

核心思路

  1. 全屏时将窗口尺寸设为屏幕分辨率,默认隐藏标题栏但保留其交互功能
  2. 监听鼠标移动事件,当鼠标进入屏幕顶部区域时自动显示标题栏,离开后隐藏
  3. 保留标题栏的关闭、返回等原生按钮,同时支持F11快捷键切换全屏状态

具体代码实现

在MAUI的Windows平台项目中添加平台专属逻辑(示例放在Platforms/Windows/FullScreenManager.cs):

using Microsoft.UI.Xaml;
using Windows.Graphics;
using Windows.UI.Core;
using Windows.UI.ViewManagement;

public class FullScreenManager
{
    private readonly AppWindow _appWindow;
    private readonly TitleBar _titleBar;
    private bool _isFullScreen;
    private Rect _originalWindowBounds;
    private bool _isTitleBarVisible;

    public FullScreenManager(AppWindow appWindow)
    {
        _appWindow = appWindow;
        _titleBar = appWindow.TitleBar;
        
        // 初始化标题栏基础设置
        _titleBar.ExtendsContentIntoTitleBar = false;
        _titleBar.IsVisible = true;
        
        // 绑定鼠标移动与按键监听
        var coreWindow = ((Window)_appWindow.Content).CoreWindow;
        coreWindow.PointerMoved += CoreWindow_PointerMoved;
        coreWindow.KeyDown += CoreWindow_KeyDown;
    }

    // 切换全屏状态
    public void ToggleFullScreen()
    {
        _isFullScreen = !_isFullScreen;
        
        if (_isFullScreen)
        {
            // 保存原始窗口位置与尺寸
            _originalWindowBounds = _appWindow.Position;
            // 把窗口铺满整个屏幕工作区(如需覆盖任务栏,改用DisplayArea.DisplayArea)
            var displayArea = DisplayArea.GetFromWindowId(_appWindow.Id, DisplayAreaFallback.Nearest);
            _appWindow.MoveAndResize(displayArea.WorkArea);
            // 默认隐藏标题栏
            HideTitleBar();
        }
        else
        {
            // 恢复原始窗口状态
            _appWindow.MoveAndResize(_originalWindowBounds);
            // 显示标题栏
            ShowTitleBar();
        }
    }

    // 鼠标移动时判断是否显示标题栏
    private void CoreWindow_PointerMoved(CoreWindow sender, PointerEventArgs args)
    {
        if (!_isFullScreen) return;
        
        var pointerY = args.CurrentPoint.Position.Y;
        // 鼠标进入顶部20px区域时显示标题栏
        if (pointerY <= 20 && !_isTitleBarVisible)
        {
            ShowTitleBar();
        }
        // 鼠标离开标题栏区域后隐藏
        else if (pointerY > _titleBar.Height && _isTitleBarVisible)
        {
            HideTitleBar();
        }
    }

    // F11快捷键切换全屏
    private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args)
    {
        if (args.VirtualKey == Windows.System.VirtualKey.F11)
        {
            ToggleFullScreen();
            args.Handled = true;
        }
    }

    private void ShowTitleBar()
    {
        _titleBar.IsVisible = true;
        _isTitleBarVisible = true;
        // 可选:添加淡入动画提升体验
        _titleBar.Opacity = 1;
    }

    private void HideTitleBar()
    {
        _titleBar.IsVisible = false;
        _isTitleBarVisible = false;
        // 可选:添加淡出动画提升体验
        _titleBar.Opacity = 0;
    }
}

在MAUI共享代码中调用该管理器:

#if WINDOWS
using Microsoft.Maui.Platform;
using Microsoft.UI.Xaml.Windowing;

// 获取当前窗口对应的WinUI AppWindow
var mauiWindow = Application.Current.Windows.First();
var winuiWindow = mauiWindow.Handler.PlatformView as Microsoft.UI.Xaml.Window;
var appWindow = winuiWindow.GetAppWindow();

// 初始化全屏管理器
var fullScreenManager = new FullScreenManager(appWindow);

// 调用切换全屏(可绑定到按钮点击或其他触发逻辑)
fullScreenManager.ToggleFullScreen();
#endif

关键细节说明

  • 标题栏交互完全保留:隐藏仅为视觉层面,点击、拖拽等原生功能不受影响
  • 触发区域可自定义:可调整代码中pointerY <= 20的数值,修改标题栏显示的触发高度
  • 屏幕适配灵活:使用DisplayArea确保窗口适配当前屏幕的分辨率与布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:23:14