4

I am trying to figure the many different ways of setting datacontext of a view to a viewmodel.

One I'm oggling at this moment goes something like this:

I have my MainWindowResource:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:vw="clr-namespace:DemoStuffPartII.View"
                xmlns:vm="clr-namespace:DemoStuffPartII.ViewModel">

<DataTemplate DataType="{x:Type vm:PersonViewModel}">
    <vw:PersonView />
</DataTemplate>

But that's also immediately where I strand. I know that I should use a ContentControl in the View. But what is the best way to configure it? How to go about this?

Garth Marenghi
  • 1,997
  • 5
  • 20
  • 38

3 Answers3

2

That is the way you can enable ViewSwitching navigation in your MVVM application.

The other missing bits are: in the view ->

<ContentControl Content="{Binding CurrentPage}" />

in the ViewModel -> (pseudo code)

Prop ViewModelBase CurrentPage.

note however that if all u want is to connect a ViewModel to a View, you can just drop the entire DataTemplate-ContentControl thing altogether, and just do this.DataContext = new SomeViewModel(); in the codebehind.

The cleanest way I know to connect VM to Views is by using the ViewModelLocator pattern. Google ViewModelLocator.

Elad Katz
  • 7,483
  • 5
  • 35
  • 66
  • Where you say Content="{Binding CurrentPage}", the CurrentPage is in my case then PersonViewModel, right? Have to ask though, why would you name the ViewModel again when it is already specified in the datatemplate? Why not go Content="{Binding}"? – Garth Marenghi Mar 31 '11 at 11:41
  • the one that's specified in the DataTemplate is the one that you're "catching". this is the "target". the one that i'm specifying in the Binding is the "source". I do feel however that you're looking at step #2 here instead of starting from the beginning. in order to just work with MVVM you should try to keep it simple at first - just work with this.DataContext = new SomeViewModel(); – Elad Katz Mar 31 '11 at 11:46
  • Yeah, I probably do some things in the wrong order, being that sometimes it's a little vague what starts where. Thanks for the anser and the tip on the ViewModelLocator pattern! – Garth Marenghi Mar 31 '11 at 11:58
  • np. Due note that both Caliburn and Prism are very good frameworks, but IMHO MVVMLight and ViewModelLocator pattern are the easiest & lightest way to go. Also, Prism works pretty well with ViewModelLocator as well. – Elad Katz Mar 31 '11 at 12:03
1

There are a couple of simple ways to just bind a ViewModel to a view. As Elad mentioned you can add it in the code-behind:

_vm = new MarketIndexVM();
this.DataContext = _vm;

or, you can specify the ViewModel as a resource in your XAML of your view:

<UserControl.Resources>
    <local:CashFlowViewModel x:Key="ViewModel"/>
    <Converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</UserControl.Resources>

and bind the DataContext of your LayoutRoot to that resource:

<Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}">
Johannes
  • 1,095
  • 6
  • 17
0

Maybe this doesn't directly answer your question, but have you looked at using an MVVM framework? For example, in Caliburn.Micro you would do (very basic example):

public class ShellViewModel : Conductor<IScreen>
{
  public ShellViewModel()
  {
    var myViewModel = new MyViewModel();
    this.ActivateItem(myViewModel);
  }
}

ShellView.xaml

<Grid>
  <ContentControl x:Name="ActiveItem" />
</Grid>

MyView.xaml

<Grid>
  <TextBlock>Hello world</TextBlock>
</Grid>

This is a viewmodel first approach.

devdigital
  • 34,151
  • 9
  • 98
  • 120
  • Yeah, this is really for myself to figure out different kinds of approaches regarding MVVM. At my work we use prism which is, if I'm not mistaken, also in the same vein as the framework you are suggesting. – Garth Marenghi Mar 31 '11 at 11:37
  • Fair enough. I would say having used both that Caliburn.Micro is superior - for example, its event aggregator is much easier to use and works with POCO objects, and it also supports convention based binding and has a very powerful action model. – devdigital Mar 31 '11 at 12:05