Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Method in View's CodeBehind from ViewModel?

I have a method within the code behind of my View (this method does something to my UI).

Anyway, I'd like to trigger this method from my ViewModel. How could this be done?

like image 571
Shai UI Avatar asked Dec 28 '11 16:12

Shai UI


People also ask

Can a ViewModel have multiple views?

It's possible that having two separate views is what you want, but it's just something to consider. Show activity on this post. I am using the prism framework and was also looking for a solution of using one viewmodel for many (child) views.


2 Answers

My (and maybe others?) difficulty with MVVM was to understand a simple thing: View knows about ViewModel. I was using bindings and commands, but they are simple strings in xaml. Because of safe resolving at run-time (safe means you can do a typo, but software will not crash) this makes view decoupled from view-model (at compile time at least). And I was always looking for solution to keep this decoupling, to example, behaviors.

Truth is, you can get access directly to view model, which is typically a DataContext of window/user control:

var vm = (MyViewModel)this.DataContext; 

Knowing that, using events probably the best way to call view method from view model, because view model don't know if there is subscriber, it just firing that event and event can be used by view or another view model.

// define in the view model public delegate void MyEventAction(string someParameter, ...); public event MyEventAction MyEvent;  // rise event when you need to MyEvent?.Invoke("123", ...);  // in the view var vm = (MyViewModel)DataContext; vm.MyEvent += (someParameter, ...) => ... // do something 
like image 77
Sinatr Avatar answered Oct 16 '22 07:10

Sinatr


You can do it like this in View (code behind).

It casts to an interface to be implemented by the ViewModel, so that you are not constrained to one specific ViewModel type.

    // CONSTRUCTOR     public SomeView()     {         InitializeComponent();          DataContextChanged += DataContextChangedHandler;     }      void DataContextChangedHandler(object sender, DependencyPropertyChangedEventArgs e)     {         var viewModel = e.NewValue as IInterfaceToBeImplementedByViewModel;          if (viewModel != null)         {             viewModel.SomeEvent += (sender, args) => { someMethod(); }         }     } 
like image 41
heltonbiker Avatar answered Oct 16 '22 06:10

heltonbiker