Quintic
WPF, MVVM, App Start-up

App Start-up with MVVM

One topic that sparks a great deal of discussion is how, on Application start-up should you associate the initial ViewModel and View when using the MVVM paradigm.

So, a few ground rules. You do not have to use MVVM to use WPF or UI development. It is a great paradigm to use, especially if you are working on a Project in team and/or in an enterprise application where long term maintenance and expected updates are anticipated. However if you are producing a one-off app to achieve a specific task, then I would say don’t sweat about it. Use code behind if that gets the job done quicker and easier.

I have come across three scenarios for implementing MVVM with WPF and startup:

  • Use the View to automagically create the ViewModel and assign it as the DataContext.
  • Create the View and ViewModel at App startup and create the linkage then.
  • Use Dependency Injection to create the ViewModel and it then create the View

Automagically create the ViewModel

Under this scenario you use XAML to instanciate the ViewModel and either reference it as the DataContext of the View, or write a couple of lines of code behind to make the ViewModel available to the rest of the application, eg:

<Window x:Class="SampleApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SampleApplication"
    xmlns:mvs="clr-namespace:ViewModels"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
   <mvs:EmployeeViewModel/>
</Window.DataContext>
public partial class MainPage : UserControl
{
    public EmployeeViewModel EmployeeViewModel
    get { return this.DataContext; }
}

Note: A more complex variation on the above is to use DataTemplates and have a Datatemplate associated with a specific ViewModel. Again XAML will automagically instanciate the required ViewModel object

I must admit this is my least favourite method, at least for the Main Windows, as I do not believe it is the responsibility of the View to create the main ViewModel. Plus you aften need to inject context into the ViewModel, and this mechansim does not provide a clean way of doing that. (For some reason using DataTemplates to automagically create the ViewModel for secondary controls/windows gives me less of a problem)

Create ViewModel at App Startup

   public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs args)
        {
            MainViewModel vm = new mainViewModel ();
            MainView view = new MainView();
            view.DataContext = vm;
            view.Show();
        }

This is my prefered mechanism, when not using a D.I. framework like PRISM. What I like about this method is that there is no dependency between the the View and ViewModel. They are both created independently. Any knowledge about each other is injected.

There are a couple of variations on the above. The View can be presented to the VM as a Constructor parameter, thereby giving the VM knowledge of the View, which can be benificial if/when DataBinding becomes problematic.

Where the View is presented to the VM, then you could set the DataContext and even trigger the View.Show from within the VM, but I am not a great fan of that, particularly triggering the Show with the VM as I don’t believe it is the responsibility of the VM to control the visibility of the View.

Dependency Injection

Great Webinar from Brian Lagunas on MVVM together with Dependency Injection. The Webinar maybe a slightly dated, but I still love it.

If you watch the Webinar, Brian details five different mechanisms for connecting the View to the ViewModel. I have listed three, because I consider a couple of the mechanisms listed by brian to be to be variations/extensions of the above.