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

MAUI中阻止主窗体关闭时如何避免页面被释放?

.NET 8 MAUI窗口关闭驻留托盘,避免内容释放的解决方案

基于.NET 8的MAUI应用中,若要实现用户关闭窗口时不退出应用、转而后台驻留托盘的需求,现有方案虽能完成窗口最小化,但存在Maui.Controls.Window及其Page属性被释放、重新打开窗口显示空白的问题。核心原因是原代码监听WinUI的Closed事件时,MAUI层面的窗口内容已进入释放流程,即便取消关闭操作也无法阻止内容销毁。

解决方案:在MAUI生命周期早期拦截关闭请求

直接监听MAUI窗口的Closing事件,在MAUI触发内容释放前取消关闭操作,再将窗口最小化到托盘,确保窗口内容不会被释放。

代码实现(MainWindow.xaml.cs)

public MainWindow()
{
    InitializeComponent();
#if WINDOWS
    // 绑定MAUI窗口的Closing事件
    Closing += MainWindow_Closing;
#endif
}

private void MainWindow_Closing(object sender, WindowClosingEventArgs e)
{
    // 取消MAUI窗口的关闭流程,阻止内容释放
    e.Cancel = true;

    // 获取WinUI平台窗口实例,将其最小化
    var platformWindow = (Microsoft.UI.Xaml.Window)Handler.PlatformView;
    IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(platformWindow);
    Microsoft.UI.WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
    Microsoft.UI.Windowing.AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
    
    if (appWindow.Presenter is Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter)
    {
        overlappedPresenter.Minimize();
    }

    // 此处可添加托盘图标显示/更新逻辑(若未实现)
}

托盘重新打开窗口的逻辑

当用户点击托盘图标时,直接激活并恢复窗口即可,因窗口内容未被释放,会正常显示原有页面:

private void TrayIcon_Click(object sender, EventArgs e)
{
    var mainWindow = App.Current.Windows.FirstOrDefault(w => w is MainWindow);
    if (mainWindow == null) return;

    // 激活窗口
    mainWindow.Activate();

    // 恢复窗口到正常状态(若处于最小化)
    var platformWindow = (Microsoft.UI.Xaml.Window)mainWindow.Handler.PlatformView;
    IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(platformWindow);
    Microsoft.UI.WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
    Microsoft.UI.Windowing.AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
    
    if (appWindow.Presenter is Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter)
    {
        overlappedPresenter.Restore();
    }
}

关键说明

  • MAUI的Window.Closing事件触发于窗口关闭流程的早期阶段,此时窗口内容尚未开始释放,设置e.Cancel = true可完全阻止关闭及后续的资源销毁。
  • 原方案监听的WinUI Closed事件属于平台层面的晚阶段事件,MAUI已在此前触发了窗口内容的释放逻辑,因此即便取消关闭也无法恢复已销毁的页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:16:18