我在棱镜中待了2天就知道了,所以在试图解释下面的导航问题时,不要因为任何错误的假设而判断我。
我们说我们只有1个地区和2个不同的观点。视图A从自定义RegionBehavior启动时加载到该区域。我使用的只是该行为中RegionManager的RequestNavigate。我没有找到更好的解决方案来设置初始视图,但这不是主要观点。
现在我们在每个视图上都有一个按钮,可以导航到另一个视图。命令在每个ViewModel上执行,并再次调用RequestNavigate。 我使用常量来注册容器(Autofac)导航的视图,并使用相同的常量来调用RequestNavigate。 一见钟情,一切正常。但后来我意识到,每次切换视图时,都会创建一个新视图和视图模型。更糟糕的是,RegionManager仍然保留对所有先前的引用,这似乎是内存泄漏。我现在可以切换到将单独的视图注册为单身,但我仍然不明白为什么RegionManager以这种方式工作。为什么他没有意识到他已经知道我要求导航并激活那个而不是创建新导航的视图?还有什么我使用常数作为当时的名字?
然后我发现了这篇文章PRISM WPF - Navigation creates new view every time,这确实解决了这个问题。只要我使用类型的名称来注册视图,一切都按预期工作。视图模型和视图模型在首次使用时创建,然后在再次请求导航时重复使用。
我仍然可以实现IRegionMemberLifetime并在KeepAlive上返回false,如果这不是我想要的行为,并且我更喜欢每次都创建新的views / viewmodels。然后至少前者从RegionManager中删除。 如果我不想删除它们并仍然想要这种旧的内存消耗行为,我仍然可以实现INavigationAware并在IsNavigationTarget中返回false。这样,RegionManager每次都会创建新实例,并且仍然保留对旧实例的引用。 反过来,当注册名称与类型名称不相等时,我无法阻止他创建新实例。在这种情况下甚至没有达到IsNavigationTarget,这告诉我RegionManager根本不会查找现有的视图。那么为什么我们在这里有两种不同的行为,这取决于我注册导航视图的名称? 当我认为两个名称相等时应用的行为应该是唯一的行为时,我错了,因为所有其他场景仍然可以使用上述附加属性创建吗?
史蒂夫
答案 0 :(得分:1)
您在容器中注册了一些名称的视图(模型)。然后可以在给定注册名称的情况下创建视图(模型)的实例。这允许RequestNavigate创建视图(模型)并在给定注册名称的情况下激活它。
但是,当RequestNavigate正在检查目标视图的可能现有实例(并且可能请求IsNavigationTarget)的区域时,它必须处理该区域中的视图(模型)的实例。他们的注册名称不可用 - 只有容器知道它们。因此,RequestNavigate假定注册名称是视图类型的Name或FullName。
因此,如果您想拥有所有功能,则应在其类型名称下注册视图(模型)。有一种方便的方法 - RegisterTypeForNavigation。