在Caliburn.Micro中将派生的ViewModels映射到基类View
本文关键字:映射 ViewModels 基类 View 派生 Caliburn Micro | 更新日期: 2023-09-27 18:12:58
我有一个基本的ViewModel和关联的View。我也有多个派生的ViewModel从基本的ViewModel,但我想使用基本视图显示。
Base 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: (map to
MyCompany.MyApp.Modules.Wizard.Views.WizardView
) -
vm:
MyCompany.MyApp.Modules.NewSpec.ViewModels.NewMaterialViewModel : WizardViewModel
- vw: (map to
MyCompany.MyApp.Modules.Wizard.Views.WizardView
)
我认为这应该可以使用ViewLocator或ViewModelLocator或NameTransformer中的映射,但我还没有弄清楚。
我正在使用双子座框架与Caliburn。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);
}
// ...
}
注:我知道有现有的向导框架(扩展WPF工具包,Avalon向导等),但我不想添加另一个第三方程序集和扩展WPF工具包向导不能正常工作。
P.P.S.我还想在其他地方使用这种样式的基础ViewModel/View映射
这里有[链接](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;
};
我知道已经很晚了…但是有一个选项可以将ViewModel
直接绑定到视图,也许这对其他人有帮助。
我还会将此绑定附加到基类构造函数。以下内容适合我:
public abstract class WizardViewModel {
protected WizardViewModel() {
// this --> points the child class
ViewModelBinder.Bind(this, new WizardView(), null);
}
}
这样,每个子类现在都使用WizardView
(无需在子类中进行任何额外的编程)。
public class NewSpecViewModel : WizardViewModel {}