使用 Unity 在 Prism for Xamarin Forms 中注册导航实例

Registering an instance for navigation in Prism for Xamarin Forms with Unity

我想在 Prism for Xamarin Forms with Unity 中注册一个用于导航的视图实例,并在导航到该实例时在关联的视图模型上接收 OnNavigatedTo。注册导航实例不是开箱即用的受支持注册,因此我创建了以下扩展:

      public static void RegisterInstanceForNavigation<TView, TViewModel>(this IUnityContainer container, TView instance, string name = null)
        where TView : Page
        where TViewModel : class
      {
        if (string.IsNullOrWhiteSpace(name))
        {
            name = typeof(TView).Name;
        }

        ViewModelLocationProvider.Register(typeof(TView).ToString(), typeof(TViewModel));
        PageNavigationRegistry.Register(name, typeof(TView));
        container.RegisterInstance(typeof(object), name, instance, new ContainerControlledLifetimeManager());
     }

在我的 app.xaml.csRegisterTypes 中,我注册了一个导航页面:

this.Container.RegisterInstanceForNavigation<AwesomeView, AwesomeViewModel>(
    new AwesomeView(),
    "seriouslyAnAwesomeView")

这似乎部分有效。我可以创建页面实例,用名称注册它并导航到它。在第一次导航时,调用来自 INavigationAware 的相应视图模型的 OnNavigatedTo;但是,在随后的页面导航中,不会调用 OnNavigatedTo。

这个注册有效吗?如果是这样,为什么不调用 OnNavigatedTo?如果没有,如何注册实例进行导航?

当用户按下后退按钮时,Prism 销毁页面并取消设置 BindingContext。如果启用了自动连接,Prism 仅在创建时设置 BindingContext 一次。因此,下一次 Prism 导航到您的页面时,绑定上下文是 null 并且 OnNaviagedTo 永远不会被调用。

如上面的评论所述,将视图保存在内存中是一种不典型的行为,而且这种行为似乎并未得到 Prism 的正式支持。

也就是说,您可以通过手动重置 Page 上的绑定上下文来相当轻松地解决此问题。 Prism 允许您像这样使 Page 导航感知:

public class MyReusablePage : ContentPage, INavigationAware
{
    ...

    public void OnNavigatingTo(NavigationParameters parameters)
    {
        if (this.BindingContext == null)
        {
            this.BindingContext = new MyReusablePageViewModel();
        }
    }

    ...
}

请注意,新的视图模型实例将与最初为您创建的 Prism 实例不同。如果您也需要视图模型实例永不更改,则需要禁用自动连接(AutoWireViewModel="False" in XAML)并向 Unity 注册您自己的单例实例。