views:

286

answers:

2

I can set the relationship between View Model and view through following DataContext syntax:

 <UserControl.DataContext>
    <view_model:MainMenuModel />
</UserControl.DataContext>

And I can also set the relationship between View Model and view through following DataTemplate syntax:

    <DataTemplate
        DataType="{x:Type viewModel:UserViewModel}">
        <view:UserView />
    </DataTemplate>

What is the difference between the two? Is the second XAML not setting the data context of a view?

+2  A: 

The DataContext of a FrameworkElement is what the element is bound to. It is fundamentally of type object. In the MVVM pattern, this is most frequently the ViewModel object, but it need not be. It is simply some context information you want to apply to that FrameworkElement. It does not directly affect the visual representation, by itself.

When WPF wants to display some object that doesn't have it's own visual representation (e.g. isn't descended from UIElement, it will look to see if a corresponding DataTemplate exists to define how it should present that data. In your example, you have said that the UserViewModel class should be presented using the UserView control, but you have not actually created either the UserViewModel or UserView.

These two concepts often go together. For example, imagine you had an ObservableCollection<object> which had in it a Foo and a Bar object. You could define different DataTemplates for Foo and Bar. Then you could bind your collection into an ItemsControl. Each object in the control would get a visual representation based on the appropriate DataTemplate from its type.

Another simple example: if you have a property on your ViewModel named DisplayObject and you simply want it to appear with whatever DataTemplate you have defined, you can use the ContentPresenter control:

<ContentPresenter DataContext="{Binding DisplayObject}"/>

Again, this results in WPF looking up the correct Template for the type and using that to construct a representation.

Ben Von Handorf
+3  A: 

Your second XAML defines a template that can be used to display an object of type viewModel:UserViewModel. It doesn't set data for anything but, if a ContentPresenter is asked to display an object of that type, it will use your template.

Your first XAML is setting the DataContext property of your control. It defines that any bindings you perform within that scope will use the DataContext as the root of the binding (unless explicitly overriden). For a simple example of DataContext at work, compare these two (both assume that "s" is the System namespace):

<StackPanel>  
  <TextBlock Text="{Binding Day, Source={x:Static s:DateTime.Now}}" />
  <TextBlock Text="{Binding Month, Source={x:Static s:DateTime.Now}}" />
  <TextBlock Text="{Binding Year, Source={x:Static s:DateTime.Now}}" />
</StackPanel>

<StackPanel DataContext="{Binding Source={x:Static s:DateTime.Now}}">  
  <TextBlock Text="{Binding Day}" />
  <TextBlock Text="{Binding Month}" />
  <TextBlock Text="{Binding Year}" />
</StackPanel>

Both StackPanels will render identically, but the second is more easily reused. (E.g.: you only have to change the binding in one place if you wanted to display a different date.)

Dan Puzey
Hi Peter,Ben Thanks to you all for the reply.I am wondering if I can set the datacontext and datatemplate of a control to the same view model ?
Ashish Ashu
@Ashish: you can set the DataContext to the ViewModel itself, but you set the DataTemplate to a template that *displays* the ViewModel - not to the viewmodel itself.
Dan Puzey