0
votes

I use MVVM navigaion. I have Main Window, and I navigate to child user controls. On the user controls I create instance of their viewmodel. So I wonder, which instance of the viewmodel will be taken, the one created on the mainwindow, or the one from the usercontrol, and is it problematic, that I create two instances? Main Window with DataTemplates:

 <Window.Resources>
        <DataTemplate DataType="{x:Type cust:CustomersListViewModel}">
            <cust:CustomerListView></cust:CustomerListView>
        </DataTemplate>
        <DataTemplate DataType="{x:Type dealer:DealersViewModel}">
            <dealer:DealersView></dealer:DealersView>
        </DataTemplate>
    </Window.Resources>

I Create instances of child user controls :

  Customers.CustomersListViewModel customersViewModel = new Customers.CustomersListViewModel();
  Dealers.DealersViewModel dealersViewModel = new Dealers.DealersViewModel();

And I bind to child user controls with : ` On the user controls I create viewmodel instance:

 <UserControl.DataContext>
        <local:CustomersListViewModel></local:CustomersListViewModel>
  </UserControl.DataContext>

So is it problematic that I create to instances of view model?

3
Don't create your views and don't create two viewmodels for each. Create a viewmodel in the mainwindowviewmodel. Use that to datatemplate into view. Like this social.technet.microsoft.com/wiki/contents/articles/…Andy

3 Answers

0
votes

You should create this:

 <Window.Resources>
      <StackPanel>
            <cust:CustomerListView></cust:CustomerListView>
            <dealer:DealersView></dealer:DealersView>
      </StackPanel>
</Window.Resources>

and in your UserControls you should do this:

  //Create Object of ViewModel in CustomerListView
  DataContext = new Customers.CustomersListViewModel();

  //Create Object of ViewModel in DealersView
  DataContext = new Dealers.DealersViewModel();
0
votes

You should not "create view-model instence" in the code of view.
In any case where appling DataTemplate by match the TargetType, the DataContext of the controls of DataTemplate will inherit the value from templated parent, because the TargetType of DataTemplate is matched by Type of the instance - this instance is that given object.

Value of DataContext => [Object] => GetType() => Match by TargetType => Apply DataTemplate, the DataContext is [Object]

A simple example:

<Window.Resource>
    <DataTemplate TargetType="local:TypeA">
        <TextBlock Text="{Binding ValueA}"/>
    </DataTemplate>
    <DataTemplate TargetType="local:TypeB">
        <TextBlock Text="{Binding ValueB}"/>
    </DataTemplate>
</Window.Resource>
<ContentControl>
    <!-- The content is a TypeA object, will apply the TypeA DataTemplate -->
    <!-- displayed 100 -->
    <local:TypeA ValueA="100"/>
</ContentControl>

And what your code do:

<Window.Resource>
    <DataTemplate TargetType="local:TypeA">
        <TextBlock Text="{Binding ValueA}">
            <TextBlock.DataContext>
                <local:TypeA ValueA="50"/>
            </TextBlock.DataContext>
        </TextBlock>
    </DataTemplate>
</Window.Resource>
<ContentControl>
    <!-- The content is a TypeA object, will apply the TypeA DataTemplate -->
    <!-- displayed 50, because you create a new instance of TypeA in the DataTemplate -->
    <local:TypeA ValueA="100"/>
</ContentControl>
0
votes

I have found a solution for intellisense by using d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}"> So I dont need to create instance in runtime from the view