伴随着prism框架的使用, 区域region的使用是避免不了的(其实可以不用region,自用做控件代码导航,那这样prism框架的这一大特性就让费掉了)。
但是各位有没有发现,一般region使用demo中都是只有在主窗体使用,但是实际使用复杂多样的, 不光在主窗体, 我们弹出的窗体;或者登录后再弹出的窗体,都是有区域region的使用需求的。
然后我们按照先登录,然后再弹主窗体的方式来使用,你就会发现当你跳转主窗体的时候会发现,region好像失效了。region导航完全失效,debug后发现regionManager里面是空的。
那么这究竟是怎么回事呢?
我们来看一下,prism的模板项目?
首先,regionName他是在主窗体中。
其次,启动后默认导航是在OnInitialized,后期验证在默认导航也是可以加载窗体的load事件中的。
好的,现在我们猜测一下,region导航生效是在,主窗体实例加载完后(region注册后)。这也就证明了为什么除了主窗体,后续其他打开的窗体region是无效的,因为他们根本没有注册过啊。
那既然是没有注册,按open窗口的时候注册下不就可以了,是的,网上有人提供了这个方案。
Prism新开一个窗体后RegionManager找不到当前region解决方法_prism regionmanager-CSDN博客
这个方案验证是可以用的,但是这种使用方式破坏了mvvm框架,导致ViewModel变成了手动赋值,还有regionmanager的实例不在是框架注册的单例 。所以我优化了下,测试是可以用的。登录=>主页面好像完成没有问题。
var mainwindow = _container.Resolve<MainWindow>();
RegionManager.SetRegionManager(mainwindow, _regionManager);
mainwindow.Show();
这就行了,真的完美解决了吗?
当然没有登录=>主窗体是一个实例到另一个实例,只注册一次当然没有问题, 那么我们每次打开的是新的实例呢,不出意料第二次打开出现异常了。。。。
为什么?那是因为你在不用实例上注册同样的regionname 当然会出现问题。发现问题解决问题,在注册之前清除要注册页面的region信息是不是可以了,找来找去 只找到IRegionCollection有删除region的方法,试一下呗。
var mainwindow = _container.Resolve<MainWindow>();
/// 重新实例主持 regionname
_regionManager.Regions.Remove(RegionHeper.MainRegionName);
RegionManager.SetRegionManager(mainwindow, _regionManager);
mainwindow.Show();
OKOK,打开关闭打开关闭,完全没有问题,region导航正常。。。有点小瑕疵可以优化,我这里是在open窗口的时候去删除临时region的,这样每次关闭后,都有留有注册信息在_regionManager中,然后持有window窗体?。。。。。