You need to enable JavaScript to run this app. Xamarin.Forms FreshMVVM 如何在App.xaml.cs校验页面未打开再打开
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms FreshMVVM 如何在App.xaml.cs校验页面未打开再打开

FreshMVVM 重复推送同页面的校验实现

不需要自己额外维护一份页面打开状态的集合,直接依托FreshMVVM本身托管的导航栈做判断就行,能完全避免自定义状态和实际导航状态不同步的问题,具体实现逻辑如下:

  • 核心判断依据:所有通过FreshPageModelResolver.ResolvePageModel<T>()生成的页面,都会自动把对应的PageModel实例设置为页面的BindingContext,我们只需要遍历当前导航栈里的所有页面,检查是否存在类型匹配的BindingContext,就能判断目标页面是否已经打开。
  • 改造后的代码完全兼容你现有的导航调用逻辑:
Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
{
    var navService = FreshIOC.Container.Resolve<IFreshNavigationService>(FreshMvvm.Constants.DefaultNavigationServiceName);

    // 获取当前导航栈托管的根NavigationPage,为空说明还没完成导航初始化,直接返回即可
    var rootNavPage = navService.CurrentNavigation;
    if (rootNavPage == null) return;

    // 收集栈内的普通导航页面
    var normalStackPages = rootNavPage.Navigation.NavigationStack;
    // 如果应用用到了模态弹窗导航,还要把模态栈的页面也纳入判断范围
    var modalStackPages = rootNavPage.Navigation.ModalStack;

    // 判断是否已经打开过目标SomePageModel对应的页面
    bool isTargetPageOpened = normalStackPages
        .Concat(modalStackPages)
        .Any(page => page.BindingContext is SomePageModel);

    if (isTargetPageOpened)
    {
        // 页面已经打开,直接终止后续推送逻辑,也可以在这里补充逻辑把已有页面切到最顶层
        return;
    }

    // 执行原有页面推送逻辑
    Page page = FreshPageModelResolver.ResolvePageModel<SomePageModel>();
    await navService.PushPage(page, null);
});

额外注意事项

  • 上述逻辑同时覆盖了普通导航和模态导航两种栈的判断,完全和框架本身的导航状态同步,不会出现自定义记录的打开状态和实际栈内容不一致的问题。
  • 如果检测到页面已经打开时,你不想直接跳过,而是希望把已经打开的实例直接激活到最前端,不需要重新新建页面,可以在检测到匹配页面后,计算当前栈顶到目标页面的层级差,逐次Pop回退到对应位置即可,不需要走新建页面+Push的流程。
  • 针对Android平台内存不足回收页面的场景,因为被回收的页面本身就会从导航栈移除,判断逻辑自然会识别到页面不存在,不会出现误判。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 11:06:04