我想在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?如果没有,如何注册实例进行导航?
答案 0 :(得分:1)
当用户按下后退按钮时,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最初为您创建的实例不同。如果您需要视图模型实例永远不会更改,则需要禁用自动连接(XAML中的AutoWireViewModel="False"
)并使用Unity注册您自己的单例实例。