在 Windows Phone 8.1 上通过 Caliburn.Micro 将单个视图用于多个 ViewModel

Igo*_*man 5 c# xaml mvvm caliburn.micro windows-phone-8.1

我有一个使用 Caliburn.Micro 的 Windows Phone 8.1 应用程序。在应用程序中,我有一些 ViewModel,它们以不同的方式和不同的逻辑获取数据,但以相同的方式显示它们。所以我想让所有这些 ViewModel 使用同一个 View。

我发现这ViewLocator.LocateTypeForModelType是一个执行将 ViewModel 映射到视图的方法。因此,我重写它以使用存在的自定义属性:

        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);
        };
Run Code Online (Sandbox Code Playgroud)

单步执行似乎工作正常。如果我导航到 ViewModel 并且该 ViewModel 有一个 UseView,我的方法将返回正确的视图。

应用程序导航到正确的视图,但从未创建 ViewModel。有点像 Caliburn.Micro 忘记了 ViewModel,或者正在寻找一个使用不同约定的视图模型,或者其他什么。

我发现ViewModelLocator.LocateTypeForViewType在导航到视图后调用该方法来解析 ViewModel。上一步中的 ViewModel 类型似乎完全被遗忘了。

ViewModelLocator.LocateTypeForViewType只能访问 View 类型,但我不知道如何使其解析上一步中的正确 ViewModel。我可以扫描所有 ViewModel 并找到具有正确属性的 ViewModel,但我不知道该选择哪一个。

关于如何解决这个问题有什么想法吗?

这是一个显示我的设置的最小项目:https ://dl.dropboxusercontent.com/u/73642/CMVMTest.zip

Nig*_*son 0

除了顶级导航之外,这种解决方案适用于其他任何地方。其原因是存在某种“双重调度:在您导航时发生”。

如您所知,FramePhoneNavigationFrame控件(取决于 WinRT 或 Silverlight)是基于其导航的视图。所以步骤看起来有点像这样。

  1. 您的代码告诉导航 servie=ce 导航到ProductViewModel.
  2. 它使用ViewLocator(您注入代码的位置)来定位ProductView并告诉Frame导航到该位置。
  3. 然后,导航服务响应导航事件ProductView并使用 定位正确的视图模型ViewModelLocator
  4. 然后它实例化并绑定该视图模型。

导航服务中这种从视图模型到视图模型的步骤会导致代码出现问题。

您应该能够创建简单继承基本视图而不添加任何内容的虚拟视图。因此,如果您MySharedView.xaml声明了以下内容就足够了。

public class SecondView : MySharedView { }

我知道这并不理想,但确实能让你得到你想要的重用。让导航服务记住导航和被导航事件之间的视图模型变得很复杂,因为所有外部因素也可能导致导航。