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

UWP BackRequested代码迁移WinUI3崩溃问题求助

WinUI3迁移中BackRequested功能的最小修改解决方案

问题原因

WinUI3无法直接使用UWP的Windows.UI.Core.SystemNavigationManager,该API针对UWP视图系统设计,与WinUI3的窗口模型不兼容,直接调用会触发内存访问异常。

最小修改方案(无需改动XAML文件)

1. 替换为WinUI3专属API

将代码中所有Windows.UI.Core.SystemNavigationManager替换为Microsoft.UI.Core.SystemNavigationManager,这是WinUI3适配的系统导航管理类。

2. 封装基类减少重复修改

由于存在4403个页面,推荐通过基类封装返回逻辑,仅需批量修改页面的继承关系即可完成迁移:

步骤1:创建基类页面

using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.UI.Core;

public class BackEnabledPage : Page
{
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        // 订阅WinUI3的返回事件
        SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        // 取消订阅,避免内存泄漏
        SystemNavigationManager.GetForCurrentView().BackRequested -= OnBackRequested;
    }

    private async void OnBackRequested(object sender, BackRequestedEventArgs e)
    {
        e.Handled = true;
        // 通用返回逻辑,可根据需求修改
        if (Frame.CanGoBack)
        {
            Frame.GoBack();
        }
        // 如需页面自定义返回逻辑,可改为virtual方法让子类重写
        // OnCustomBackAction(e);
    }

    // 可选:子类自定义返回逻辑的入口
    // protected virtual async void OnCustomBackAction(BackRequestedEventArgs e)
    // {
    //     if (Frame.CanGoBack)
    //     {
    //         Frame.GoBack();
    //     }
    // }
}

步骤2:批量修改页面继承关系

使用编辑器的批量替换功能(如Visual Studio正则表达式替换),将所有页面类的继承从Page改为BackEnabledPage:

  • 查找:public sealed partial class (\w+) : Page
  • 替换:public sealed partial class $1 : BackEnabledPage

3. 单个页面的修改方案(若无需基类)

如果仅修改部分页面,直接调整页面代码:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    // 替换为WinUI3的SystemNavigationManager
    Microsoft.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += BackRequested;
    // 原页面其他逻辑...
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
    // 必须取消订阅,防止内存泄漏
    Microsoft.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested -= BackRequested;
    // 原页面其他逻辑...
}

// 移除static修饰符,避免上下文异常
private async void BackRequested(object sender, Microsoft.UI.Core.BackRequestedEventArgs e)
{
    e.Handled = true;
    // 原返回操作逻辑...
    if (Frame.CanGoBack)
    {
        Frame.GoBack();
    }
}

关键注意事项

  • 必须在OnNavigatedFrom中取消事件订阅,否则会导致页面实例被意外持有,引发内存泄漏。
  • 移除BackRequested方法的static修饰符,因为返回操作通常依赖页面实例的Frame等成员,static方法会导致上下文访问异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:58:25