Bish25
Bish25

Reputation: 616

MVVM Binding between two user controls with separate view models

i have a window which loads a Customer table and another user control of input fields, when i select i wish to populate the user control inputs. I currently have a datagrid that a selected item is set in the CustomerViewModel through binding. When this is selected it updates a textbox with the selected items property such as name, email, etc. I have a CustomerSettingsViewModel which contains multiple input fields. I am trying to bind the selected item to inputs within this model, however as the CustomerViewModel doesn't know about the CustomerSettingsViewModel i cant see the binds within the textbox inputs.

The views are loaded using DataTemplate using the datatype.

MainWindow.xaml

    <Window.Resources>
            <DataTemplate  DataType="{x:Type VM:CustomerVM}">
                <View:Customers/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type VM:CustomerSettingsVM}">
                <View:CustomerSettings />
            </DataTemplate>
            <DataTemplate DataType="{x:Type VM:SuppliersVM}">
                <View:Suppliers/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type VM:SuppliersSettingsVM}">
                <View:SupplierSettings/>
            </DataTemplate>
        </Window.Resources>

<ContentControl Content="{Binding SelectedMain}"  Margin="0,135,0,10" Grid.ColumnSpan="2"/>
<ContentControl Content="{Binding SelectedSettings}"  Margin="105,53,10,45"/>

These are set and get the correct views depending on the datatype that being presented.

MainVM.cs

Customer = new CustomerVM();
CustomerSettings = new CustomerSettingsVM();
SelectedMain = Customer;
SelectedSettings = CustomerSettings;

within the CustomerVM i have a get and selected with binds to anything within the customer view, however how can i get the customer settings view to see the selected customer has changed and populate the inputs?

CustomerVM.cs

 public Customer SelectedCustomer
        {
            get { return _selectedCustomer; }
            set
            {
                _selectedCustomer = value;
                RaisePropertyChangedEvent("SelectedCustomer");
            }
        }

i have upload a simple solution of my problem onto GitHub Might give a better understanding of what i am trying to achieve

Upvotes: 0

Views: 1450

Answers (1)

Ouarzy
Ouarzy

Reputation: 3043

I think you missed a few concepts about MVVM, maybe you should go back to basics. Basically, your viewmodels have to be a "testable copy" of your view. So if your target is to build a Customer View containing Customer Settings, what you need is:

  • a CustomerViewModel with a CustomerSettingsViewModel property
  • a CustomerView using CustomerViewModel as datacontext
  • a CustomerSettingsView declared into your CustomerView binded to the CustomerSettingsViewModel from the CustomerViewModel

Another way to put this: if you want a view to contain another view, you can have a viewModel to contain another viewModel.

This other question could show you how to use a vm as a property of another vm.

Please see my proposed solution using your GitHub example. Basically your problem is that you should not use directly the Customer Model in a View, but create a CustomerVm instead, and just delete the CustomerSettingVm. You might understand better my implementation by reading how I'm used to deal with MVVM.

Hope it helps.

Upvotes: 2

Related Questions