将派生的ViewModel映射到Caliburn.Micro中的基类View

时间:2014-07-15 17:40:51

标签: c# wpf mvvm caliburn.micro

我有一个基本的ViewModel和相关的View。我还有来自基本ViewModel的多个派生ViewModel,但我想使用基本视图进行显示。

基本ViewModel和View:

  • vm:MyCompany.MyApp.Modules.Wizard.ViewModels.WizardViewModel
  • vw:MyCompany.MyApp.Modules.Wizard.Views.WizardView

派生自WizardViewModel

  • vm:MyCompany.MyApp.Modules.NewSpec.ViewModels.NewSpecViewModel : WizardViewModel
  • vw :(映射到MyCompany.MyApp.Modules.Wizard.Views.WizardView

  • vm:MyCompany.MyApp.Modules.NewSpec.ViewModels.NewMaterialViewModel : WizardViewModel

  • vw :(映射到MyCompany.MyApp.Modules.Wizard.Views.WizardView

我认为应该可以使用ViewLocator or ViewModelLocatorNameTransformer中的映射,但我还没有想到它。

我正在使用Gemini FrameworkCaliburn.Micro v1.5.2(我计划尽快升级到v2)。

这是我尝试过的一件事:

public class NewSpecViewModel : WizardViewModel
{
    // ...
    static NewSpecViewModel()
    {
        // Escape the '.' for the regular expression
        string nsSource = typeof(NewSpecViewModel).FullName.Replace(".", @"\.");
        string nsTarget = typeof(WizardViewModel).FullName;
        nsTarget = nsTarget.Replace("WizardViewModel", "Wizard");
        // nsSource = "MyCompany\\.MyApp\\.Modules\\.NewSpec\\.ViewModels\\.NewSpecViewModel"
        // nsTarget = "MyCompany.MyApp.Modules.Wizard.ViewModels.Wizard"
        ViewLocator.AddTypeMapping(nsSource, null, nsTarget);
    }
    // ...
}

P.S。我知道有现有的向导框架(Extended WPF ToolkitAvalon Wizard等),但我不想添加另一个第三方程序集,并且扩展WPF工具包向导无法正常工作

P.P.S。我还想在其他地方使用这种基本的ViewModel / View映射。

2 个答案:

答案 0 :(得分:5)

这是[链接](https://caliburnmicro.codeplex.com/discussions/398456)以正确的方式执行此操作。

编辑:由于codeplex正在关闭,以下是讨论中的代码:

var defaultLocator = ViewLocator.LocateTypeForModelType;
ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
{
    var viewType = defaultLocator(modelType, displayLocation, context);
    while (viewType == null && modelType != typeof(object))
    {
        modelType = modelType.BaseType;
        viewType = defaultLocator(modelType, displayLocation, context);
    }
    return viewType;
};

答案 1 :(得分:1)

我知道已经晚了... 但是可以选择将ViewModel直接绑定到视图,这可能会对其他人有所帮助。

我还会将此绑定附加到基类构造函数。以下适用于我:

public abstract class WizardViewModel {
    protected WizardViewModel() {
        // this --> points the child class
        ViewModelBinder.Bind(this, new WizardView(), null);
    }
}

这样,每个孩子现在都使用WizardView(在子类中没有任何额外的编程)。

public class NewSpecViewModel : WizardViewModel {}