Specifying the View which corresponds a View Model

Apr 15, 2011 at 3:52 PM

Hi,

Is there a way within caliburn to override the default ViewLocator and specify the View I wish to be created?

I have two view different models which derive from the same abstract base view model, and the both need to hook up to same View. 

Best Regards

David

Apr 15, 2011 at 4:28 PM

Are you speaking about view fallback in respect of the view-model inheritance tree (e.g. given ViewModelA and ViewModelB, inheriting from it, both should share ViewA)?

If so, I am using a code that does as much:

ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
                                                 {
                                                     Type viewType;
                                                     var currentModelType = modelType;
                                                     do
                                                     {
                                                         var viewTypeName = (currentModelType.FullName ?? string.Empty).Replace("ViewModel", "View");
                                                         if (context != null)
                                                         {
                                                             var index = viewTypeName.LastIndexOf('.');
                                                             if (index < 0)
                                                                 index = 0;

                                                             viewTypeName = viewTypeName.Substring(0, index) + "." + context + viewTypeName.Substring(index);
                                                         }

                                                         viewType = (from assmebly in AssemblySource.Instance
                                                                     from type in assmebly.GetExportedTypes()
                                                                     where type.FullName == viewTypeName
                                                                     select type).FirstOrDefault();

                                                         //Recursively search for a view compatible with a view-model implementation...
                                                         currentModelType = currentModelType.BaseType;
                                                     }
                                                     while (viewType == null && currentModelType != null);

                                                     return viewType;
                                                 };
Note that the above code uses a different conenvention regarding views and contextes (i.e. given My.ViewModels.ViewModelClass and context MyContext, the view is identified as My.Views.MyContext.ViewClass), but I suppose you can revert it to the default approach easily.

Apr 18, 2011 at 11:26 AM

Thanks for the assistance Bladewise.

My scenario would be something like the following.  MyViewModelA and MyViewModelB both inherit from MyViewModelBase<T>.  Therefore the view locator needs to handle generic base class type names. As you pointed out , reverting this part of the method back to the default implementation handles this.

Many Thanks

David

 

On a seperate note, for any others whom this approach doesnt work. I found this blog post on how to specify the required view type based on using a custom attribute in the ViewModel class definition;

http://www.emidee.net/blog/index.php/post/2010/09/30/%5BCaliburn-Micro%5D-How-to-use-the-same-view-for-multiple-view-models