Passing data between 2 viewmodels in WPF MVVM

Kalpana 291 Reputation points
2023-10-31T08:09:39.0433333+00:00

Hi

What is the best way to pass data between 2 view models ?

I have View1, connected to ViewModel1,

View2, connected to ViewModel2

View1 returns a property called FullName and I want this to appear in a textbox in View2.

ViewModel1

 public class LoginVM : ViewModelBase
    {
        private User user;
       
        private GndManDBCtxtNew _context;

        private MyRepository _repository;
        public ICommand LoginCommand { get; }

       

        public LoginVM()
        {
            user = new User();
            _context = new GndManDBCtxtNew();
            _repository = new MyRepository(_context);
            LoginCommand = new RelayCommand((param) => LoggedIn(param));
        }

    

        public string Password
        {
            get => user.Password;
            set
            {
                user.Password = value;
                OnPropertyChanged(nameof(Password));
            }
        }

        public string FullName
        {
            get => user.FullName;
            set
            {
                user.FullName = value;
                OnPropertyChanged(nameof(FullName));
            }
        }

        //this is the command to run
        internal void LoggedIn(object parameter)
        {
            SqlParameter[] param = new SqlParameter[] {
                        new SqlParameter() {
                            ParameterName = "workerid",
                            SqlDbType =  System.Data.SqlDbType.NVarChar,
                            Size = 50,
                            Direction = System.Data.ParameterDirection.Input,
                            Value = parameter
                        },
                      };

            List<User> test = _repository.CheckLoginPassword(param).ToList();
            FullName = test[0].FullName;

            MessageBox.Show($"Logged in successfull as {test[0].FullName}");
           
        }

      
    }

ViewModel2

Developer technologies Windows Presentation Foundation
Developer technologies .NET Other
Developer technologies C#
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 48,676 Reputation points Microsoft External Staff
    2023-11-02T05:40:50.45+00:00

    Hi,@Kalpana. To achieve data transfer between the two ViewModels , you could establish a communication channel between the two ViewModels. One way to accomplish this is by setting up an intermediary class that acts as a mediator between the ViewModels. Here is an example of how to modify the ViewModel to facilitate data transfer.

    View1:

     <StackPanel  >
    
            <TextBox Name="name" Text="{Binding FullName, UpdateSourceTrigger=PropertyChanged}" />
          
            <Button Content="login"  Command="{Binding LoginCommand}"     />
        </StackPanel>
    

    View2:

    
        <Grid >
            <TextBlock Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}" Width="100" Background="AliceBlue"  />
        </Grid>
    
    

    Codebedhind:

      public partial class MainWindow : Window
        {
           
            public MainWindow()
            {
                InitializeComponent();
                var viewModel1 = new LoginVM();
                var viewModel2 = new LoggedInVM();
                DataContext = viewModel1;
              
                var view2 = new View2 { DataContext = viewModel2 };
    
           
                view2.Show();
    
            }
        }
      
        public class LoginVM : ViewModelBase
        {
            private User user;
    
         
            public ICommand LoginCommand { get; }
    
    
    
            public LoginVM()
            {
                user = new User();
      
                LoginCommand = new RelayCommand((param) => LoggedIn(param));
            }
    
            public event EventHandler<string> FullNameChanged;
    
            public string Password
            {
                get => user.Password;
                set
                {
                    user.Password = value;
                    OnPropertyChanged(nameof(Password));
                }
            }
    
            public string FullName
            {
                get => user.FullName;
                set
                {
                    user.FullName = value;
                    OnPropertyChanged(nameof(FullName));
                    Mediator.NotifyViewModel1FullNameChanged(value);
                }
            }
    
          
            internal void LoggedIn(object parameter)
            {
              
    
                
                FullName = FullName;
    
                MessageBox.Show($"Logged in successfully as {FullName}");
            }
    
    
        }
        public static class Mediator
        {
            public delegate void ViewModel1FullNameChangedEventHandler(string fullName);
            public static event ViewModel1FullNameChangedEventHandler ViewModel1FullNameChanged;
    
            public static void NotifyViewModel1FullNameChanged(string fullName)
            {
                ViewModel1FullNameChanged?.Invoke(fullName);
            }
        }
        public class LoggedInVM : ViewModelBase
        {
            private User user=new User();
            private readonly LoginVM loginVM;
            private string name;
    
            public string Name
            {
                get => name;
                set
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
    
         
    
            public LoggedInVM()
            {
                user = new User();
    
            
                Mediator.ViewModel1FullNameChanged += UpdateName;
            }
            private void UpdateName(string fullName)
            {
                Name = fullName;
            }
    
    
        }
        public class User
        {
            public int Id { get; set; }
            public string FullName { get; set; }
            public string Password { get; set; }
        }
       
        public class ViewModelBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
            protected virtual void SetValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
            {
                field = value;
                OnPropertyChanged(propertyName);
            }
        }
        public class RelayCommand : ICommand
        {
            private readonly Action<object> _execute;
            private readonly Predicate<object> _canExecute;
    
            public RelayCommand(Action<object> execute)
                : this(execute, null)
            {
            }
    
            public RelayCommand(Action<object> execute, Predicate<object> canExecute)
            {
                if (execute == null)
                    throw new ArgumentNullException("execute");
                _execute = execute;
                _canExecute = canExecute;
            }
    
            public bool CanExecute(object parameter)
            {
                return _canExecute == null ? true : _canExecute(parameter);
            }
    
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }
    
            public void Execute(object parameter)
            {
                _execute(parameter);
            }
        }
    
    
    

    The result:

    User's image

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.