在Windows Phone 8.1上使用Caliburn.Micro的多视图模型使用单一视图
本文关键字:视图 Windows 模型 单一 Micro Caliburn Phone | 更新日期: 2023-09-27 18:24:57
我有一个使用Caliburn.Micro.的Windows Phone 8.1应用程序。在该应用程序中,我有一些ViewModel,它们以不同的方式和逻辑获取数据,但以相同的方式显示。所以我想让所有的ViewModel都使用同一个View。
我发现ViewLocator.LocateTypeForModelType
是一个用于将ViewModels映射到Views的方法。因此,当存在时,我覆盖它以使用我的自定义属性:
var original = ViewLocator.LocateTypeForModelType;
ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
{
var useViewAttributes = modelType.GetTypeInfo().GetCustomAttributes<UseViewAttribute>(true);
if (useViewAttributes.Count() == 1)
{
var viewTypeName = string.Concat(modelType.Namespace.Replace("Model", string.Empty), ".", useViewAttributes.First().ViewName);
var type = AssemblySource.FindTypeByNames(new List<string>() { viewTypeName });
return type;
}
return original(modelType, displayLocation, context);
};
通过它似乎工作得很好。如果我导航到一个ViewModel,并且该ViewModel有一个UseView,那么我的方法会返回正确的View。
应用程序导航到正确的视图,但从未创建ViewModel。有点像Caliburn。Micro忘记了ViewModel,或者正在寻找一个使用不同约定的。
我发现ViewModelLocator.LocateTypeForViewType
是在导航到视图后调用的,以解析ViewModel。上一步中的ViewModel类型似乎被完全遗忘了。
在ViewModelLocator.LocateTypeForViewType
中,我只能访问View类型,我不知道如何使它解析上一步中的正确ViewModel。我可以扫描所有的ViewModel并找到具有正确属性的,但我不知道该选择哪一个。
关于如何处理这个问题,有什么想法吗?
以下是一个显示我的设置的最小项目:https://dl.dropboxusercontent.com/u/73642/CMVMTest.zip
除了顶级导航之外,这种解决方案在其他任何地方都适用。原因是有一种"双重调度:当你导航时会发生。
如您所知,Frame
或PhoneNavigationFrame
控件(取决于WinRT或Silverlight)在其导航中是基于视图的。所以台阶看起来有点像这样。
- 您的代码告诉导航服务导航到
ProductViewModel
- 它使用
ViewLocator
(您已在其中注入代码)来定位ProductView
,并告诉Frame
导航到该位置 - 导航服务然后对
ProductView
的导航事件作出响应,并使用ViewModelLocator
定位正确的视图模型 - 然后它实例化并绑定这个视图模型
导航服务中的这种视图模型到视图模型的步骤会导致代码出现问题。
您应该能够创建伪视图,只需继承基本视图而不添加任何内容。因此,如果您有MySharedView.xaml
,那么声明下面的内容就足够了。
public class SecondView : MySharedView { }
我知道这并不理想,但确实能让你得到想要的重用。让导航服务记住导航和导航事件之间的视图模型会变得复杂,因为所有外部因素也会导致导航。