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.

Original source