Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM - Does the View really need have to have a default constructor?

I'm just getting started with the MVVM pattern in WPF and I decided that the most elegant way to structure my code was injecting the view-model in to the view's constructor.

This is all well and good, but ReSharper gives a warning in the XAML that my view doesn't have a default constructor. I'm assuming that this is so that I can construct my view in XAML if required, but that's only a guess.

What am I giving up by requiring my view to take a view-model in the constructor?

Edit: My view constructor looks like this:

public ExampleView(ExampleViewModel viewModel)
{
    if (viewModel == null) throw new ArgumentNullException("viewModel");
    DataContext = viewModel;
}

Answer: I settled on the following set up, where the DesignTime namespace contains mocked up versions of the ViewModel for testing and design time support.

ExampleView.xaml.cs

public ExampleView()
{
    InitializeComponent();
}

public ExampleView(IExampleViewModel viewModel)
    : this()
{
    DataContext = viewModel;
}

ExampleView.xaml

<UserControl
    x:Class="Wpf.Examples.ExampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:DesignTime="clr-namespace:Wpf.Examples.DesignTime">

    <UserControl.DataContext>
        <DesignTime:ExampleViewModel/>
    </UserControl.DataContext>

</UserControl>
like image 909
Jacob Stanley Avatar asked Apr 23 '09 06:04

Jacob Stanley


1 Answers

As you correctly recognized, requiring a non-default constructor will deny you using that control from XAML. That also means no more design-support and your designers will probably hate you. Finally you break all sorts of nice data binding scenarios. Like using the control as an ItemTemplate.

As a remedy for the missing design support, I would suggest implementing a default constructor which creates a mocked view-model which doesn't need any infrastructure. That way you can support design mode very elegantly and putting the view in a XAML file (e.g. for testing) will do something sensible.

As a remedy for the missing data binding support, you should ponder whether it might be better to consume the view model via the DataContext of your WPF control. This is common in WPF and---as far as I can tell---the intended way to pass the model to the view in WPF.

like image 81
David Schmitt Avatar answered Sep 28 '22 01:09

David Schmitt