使用Unity为Xamarin Forms注册Prism导航实例

时间:2016-12-22 20:17:40

标签: xamarin.forms unity-container prism

我想在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.cs,RegisterTypes中,我注册了一个导航页面:

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

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

此注册有效吗?如果是这样,那为什么不会被称为OnNavigated?如果没有,如何注册实例进行导航?

1 个答案:

答案 0 :(得分:1)

当用户按下后退按钮时,Prism会破坏页面并取消设置BindingContext。如果启用了自动布线,则Prism仅在创建时设置BindingContext一次。因此,下次Prism导航到您的页面时,绑定上下文为nullOnNaviagedTo永远不会被调用。

正如上面的评论中所提到的,保持内存中的视图有些不典型的行为,并且看起来Prism没有正式支持这种行为。

话虽如此,您可以通过手动重置Page上的绑定上下文来相当轻松地解决此问题。 Prism允许您使Page导航识别如下:

public class MyReusablePage : ContentPage, INavigationAware
{
    ...

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

    ...
}

警惕新视图模型实例与Prism最初为您创建的实例不同。如果您需要视图模型实例永远不会更改,则需要禁用自动连接(XAML中的AutoWireViewModel="False")并使用Unity注册您自己的单例实例。