Search code examples
wpfmvvmviewmodelinteraction

What is the correct way to pass data between view models?


I've just started with MVVM and I have been reading up on it and doing some examples. I've managed to create an application that will read from the database and then populate into a listbox. I am having difficulty in trying to link up the selected item into another view and then do a bit of processing in that views viewModel. Please can somebody explain to me the correct way to get the currently selected item from view1 listbox and then on view2 label just to output the selected item?

Here is my XAML:

<local:SecondView Margin="499,30,0,20">
        <local:SecondView.DataContext>
            <v:MainViewModel />
        </local:SecondView.DataContext>
    </local:SecondView>
        <Button Height="22" HorizontalAlignment="Left" Margin="8,4,0,0" Name="button1" VerticalAlignment="Top" Width="48" Command="{Binding Path=GetDataCommand}">Button</Button>
    <ListBox ItemsSource="{Binding Path=FileData}"   SelectedItem="{Binding dr}"  Height="330" HorizontalAlignment="Left" Margin="149,30,0,0" Name="listBox1" VerticalAlignment="Top" Width="250" DisplayMemberPath="DDFName" />

This piece of code is in my viewModel1:

private DataRowView _dr;
    public DataRowView dr
    {
        get{
            return _dr;
        }

        set
        {
            _dr = value;
            OnPropertyChanged("dr");}
    }

I want to somehow get viewModel2 to get the new value of dr (which is the item selected in view1 listbox) and then on view2 I want to show some details

Thanks in advance!


Solution

  • Your ViewModel2 class is depending on the Row --> One possibility to inject the dependency in ViewModel2 is to pass it by constructor.

    public class ViewModel1
    {
        private DataRowView _dr;
        public DataRowView dr
        {
            get
            {
                return _dr;
            }
    
            set
            {
                _dr = value;
                OnPropertyChanged("dr");
    
                this.DetailView = new ViewModel2(value); //On Change of the selected Row create a new viewModel which serves as detail view
            }
        }
    
        private ViewModel2 _DetailView;
        public ViewModel2 DetailView
        {
            get
            {
                return _DetailView;
            }
            set
            {
                if (_DetailView != value)
                {
                    _DetailView = value;
                    RaisePropertyChanged(() => this.DetailView);
                }
            }
        }
    }
    
    public class ViewModel2
    {
        public ViewModel2(DataRowView row)
        {
            this.Row = row;
        }
    
        private DataRowView _Row;
        public DataRowView Row
        {
            get
            {
                return _Row;
            }
            set
            {
                if (_Row != value)
                {
                    _Row = value;
                    RaisePropertyChanged(() => this.Row);
                }
            }
        }
    }
    

    and in your XAML you can set the datacontext directly to the detail view:

    <local:SecondView Margin="499,30,0,20" DataContext="{Binding DetailView, Mode=OneWay}" />