Tuesday, April 22, 2014

Using the Convention Based Prism 5.0 View-Model Locater

All the information you need to use the View-Model Locator is in the Prism 5.0 documents, but if you've been there and had some trouble this may help. The key here is that this is all about convention over configuration. You can configure what view goes with what view model per the docs like this:
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
        {
            ...
            return viewModelType;
        });
However, if you just name things according to the specified convention, things will auto wire with a few of the normal expected issues. First off let's get to what the convention is. When I set up a new project, I typically make two folders - one named ViewModels and one named Views. I've seen other folks use the singular ViewModel and View, but if you want this to work, you'd better make those plural. The folders are Namespace providers so .ViewModels.MyScenicViewModel, and .Views.MyScenicView. That was my downfall... The expected convention is that the view not have any suffix of View, but the View-Model must have a ViewModel suffix. So to adjust what we had before, it would look like this: .ViewModels.MyScenicViewModel and Views.MyScenic. This threw me for a bit of a loop but yes, it is clearly stated in the Prism documents. The next gotcha is the normal View-Model must have a default constructor. If it doesn't, you need to tell the Prism VM locater how to resolve its dependencies. In your app initialization add the following:
    ViewModelLocationProvider.SetDefaultViewModelFactory(t => _container.Resolve(t));
The view must implement the empty IView interface found in the Microsoft.Practices.Prism.Mvvm namespace.
  public partial class Wizard : Window, IView
    {
        public Wizard()
        {
            InitializeComponent();
        }
    }
And finally set the auto wire up flag to true in your views xaml.
<Window x:Class="MyProject.Views.Wizard"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mvvm="clr-namespace:Microsoft.Practices.Prism.Mvvm;assembly=Microsoft.Practices.Prism.Mvvm.Desktop"
        Title="Wizard" Height="600" Width="800"
        mvvm:ViewModelLocator.AutoWireViewModel="True">
That's about all there is to it For more info, read the Prism 5.0 Developers Guide.

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This is not the case anymore, the View can now have suffix "View". see https://github.com/PrismLibrary/Prism/commit/463f18d68cf8a419e05cb2aedbbf76ab3b7799d8

    ReplyDelete