Mapping derived ViewModels to base class View in Caliburn.Micro
c#, caliburn.micro, mvvm, wpf
Solution
Here's [a link] (https://caliburnmicro.codeplex.com/discussions/398456) to right way to do this.
EDIT: Since codeplex is shutting down, here is the code from the discussion:
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;
};
Problem
I have a base ViewModel and associated View. I also have multiple derived ViewModels from the base ViewModel, but I'd like to use the base View for display. Base ViewModel and View: - vm: `MyCompany.MyApp.Modules.Wizard.ViewModels.WizardViewModel` - vw: `MyCompany.MyApp.Modules.Wizard.Views.WizardView` Derived from `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`) I think this should be possible using the mapping in ViewLocator or ViewModelLocator or NameTransformer, but I haven't figured it out yet. I am using the Gemini Framework with Caliburn.Micro v1.5.2 (I plan on upgrading to v2 soon). Here is one of the things I have tried: ``` 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. I know there are existing Wizard frameworks (Extended WPF Toolkit, Avalon Wizard, etc), but I don't want to add another 3rd party assembly and the Extended WPF Toolkit Wizard wasn't working properly. P.P.S. I also want to use this style of base ViewModel/View mapping elsewhere.