views:

549

answers:

4

I can see two ways to hook up the ViewModel to the View. One is in XAML and the other thru dependancy injection in the code behind.

Which method is more preferable? I prefer the xaml method because I don't want any code in the code behind at all, but is there any issues with one over the other?

<navigation:Page x:Class="MyNamespace.MyViewModel" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:ViewModel="clr-namespace:MyNameSpace.MyViewModel"
   xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   Title="ViewModel Page" >

    <navigation:Page.Resources>
        <ViewModel:MyViewModel x:Key="ViewModel"></ViewModel:MyViewModel>
    </navigation:Page.Resources>

    <Grid x:Name="LayoutRoot" Background="White" 
          DataContext="{StaticResource ViewModel}">

    </Grid>
</navigation:Page>

OR

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace MyNamespace
{
    public partial class MyView : Page
    {
        public MyView()
        {
            InitializeComponent(MyViewModel viewModel);

            this.DataContext = viewModel;
        }
    }
}
A: 

The way you've it here, I would go with XAML. There are other ways to set to DataContext property. If you're interested, look at Microsoft CAG framework for WPF.

Vasu Balakrishnan
+3  A: 

Shawn has a good post on View or ViewModel first. Having the VM in the XAML gives you Blendability (seeing sample data in Blend) which is cool, but the price is having to push info back into the View. John Papa has moved away from this approach for this reason.

I'm using Shawn's Marriage idea (see the link above).

HTH -Erik

Erik Mork
Hmm.. thanks for the link. I'm reading it now. I think I need to read it a few more times because I'm not getting something. Shawn says "In both of these methods I tend not to like the sticky-ness of the view to the view-model. Also, both of these imply a one-to-one relationship which while the common case, is not the always case." but with View-First the many views can be databound to one VM. Could a view be bound to more than one VM? hmmm.. again, I guess if your V was a simple grid to might want to have it bound to different VMs.
Robert Kozak
So far, I'm a fan of keeping a one-to-one relationship between Vs and VMs. Which doesn't mean I'm against a hierarchy. That is, a View might contain sub-views each with its own VM, and this has seemed to work fairly well.
Erik Mork
In our application we have a Standard grid view that just displays rows of data. That data can be from different ViewModels so keeping it one to one doesn't make sense for us. No point in having multiple Grid Views when they are all the same except for the data it contains.
Robert Kozak
PS. I really enjoy your videos. Keep it up!
Robert Kozak
I see. I thought you were referring to a view being bound to multiple vms at the same time... lol. Thanks!
Erik Mork
A: 

I've set the VM in code because this make testing of the View a lot easier. Justin Angel has a great post for this:

public partial class Page : UserControl
{
    private PageViewModel _viewModel = new PageViewModel();

    public PageViewModel ViewModel
    {
        get { return _viewModel; }
        set { _viewModel = value; }
    } 

    public Page()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        this.DataContext = ViewModel;
    }

}

I found his post to be very useful for learning about the intricasies of testing surrounding the MVVM pattern.

http://silverlight.net/blogs/justinangel/archive/2009/02/25/silverlight-unit-testing-rhinomocks-unity-and-resharper.aspx

HTH, Mark

Mark Cooper
Thanks for the link. I'm still reading it now but I prefer Shawn's method right now. I need to spend some more time thinking about it but I want a clearly decoupled VM and V.
Robert Kozak
+4  A: 

I use a class I dub a "Screen" that handles the MVVM triad. I started out iwth a V being inject into a VM, then a VM as a resource in a V, but in the end the Screen concept worked best for me. It allows me to use a V and a VM without being coupled to each other. It also abstracts away other functionality in my overall presentation framework. Here is the constructor for my Screen class as an example:

    public CatalogItemScreen(IUnityContainer container) : base(container)
    {
        this.ViewModel = Container.Resolve<ICatalogItemViewModel>();
        this.View = Container.Resolve<CatalogItemView>();
        this.View.DataContext = this.ViewModel;
    }

Notice that VM is created in the Screen, the V is created here, and the 2 are bound to each other. This sample uses Unity and Prism, but it is not necessary to achieve this.

John Papa