Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Pass View Constructor Parameter to View Model

Tags:

c#

mvvm

wpf

I have a View and ViewModel.

MyView
{
  MyView(int id)
  {
    InitializeComponent();
  }
}

 MyViewModel
    {
     private int _id;
      public int ID
       {
        get { return _id; }
        set { _id= value; OnPropertyChanged("_id"); }
       }
    }

I am setting the data Context on my XAML as :

<Window.DataContext>
        <vm:MyViewModel/>
</Window.DataContext>

On Click of a button I am showing my View as :

Application.Current.Dispatcher.Invoke(() => new MyView(id).Show());

Now , How do I pass id from MyView(id) to MyViewModel.ID.

like image 886
Simsons Avatar asked Apr 09 '15 09:04

Simsons


3 Answers

Since the DataContext gets created after the InitializeComponent() call, you can just pass it to the ViewModel afterwards:

MyView
{
   MyView(int id)
   {
     InitializeComponent();
     ((MyViewModel)DataContext).ID = id;
   }
 }
like image 105
Lennart Avatar answered Oct 16 '22 00:10

Lennart


You can do one of the following solutions :

1) Use the Messenger pattern :

You can use the Messenger Pattern, if you are using MVVMLight for example, you can do the following :

In the ViewModel do :

MyViewModel
{
     private int _id;
     public int ID
     {
        get { return _id; }
        set { _id= value; OnPropertyChanged("_id"); }
     }

     Public void InitilizeMessenger()
     {
         Messenger.Default.Register(this,"To MyViewModel", (int id) => ID = id);
     }
     public MyViewModel()
     {
        InitilizeMessenger();
     }
}

You make the ViewModel ready for receiving messages by registering to the Messenger.

in the View do :

MyView
{
  MyView(int id)
  {
    InitializeComponent();
    Messenger.Default.Send<int>(id,"To MyViewModel");
  }
}

Broadcast a message, by sending it accompanied by the "To MyViewModel" tag, so it can be caught by the MyViewModel.

2) Access DataContext from the View :

MyView
{
  MyView(int id)
  {
    InitializeComponent();
    ((MyViewModel)this.DataContext).ID = id;
  }
}

The second solution is straightforward and simpler, I gave the first one just for in case of more complicated scenarios.

like image 5
AymenDaoudi Avatar answered Oct 15 '22 22:10

AymenDaoudi


Firstly, OnPropertyChanged("_id") is wrong, beacuse _id is a variable, not a property. You must change as OnPropertyChanged("ID"). You can assign viewModel in code behind.

class MyView
{
      MyView(int id)
        :this(new MyViewModel(id))
      {
      }

      MyView(MyViewModel viewModel)
      {
        InitializeComponent();
        this.DataContext = viewModel;
      }
}

class MyViewModel
{
     private int _id;
     public int ID
     {
        get { return _id; }
        set { _id= value; OnPropertyChanged("ID"); }
     }
     public MyViewModel(int id)
     {
        ID=id;
     }
}
like image 2
Doctor Avatar answered Oct 16 '22 00:10

Doctor