Calling a Method in View's CodeBehind from ViewModel?

31,464

Solution 1

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

Solution 2

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(); }
        }
    }

Solution 3

According to MVVM pattern ViewModel is not aware of View, so this is not acceptable. To interact with ViewModel View could trigger a command, also you can use bindings. Moreover, you should not move UI-specific things like BusyIndicator to ViewModel level.

Please provide more details regardign your concrete use case - when you want to call a View's method and what this method does.

Share:
31,464
Shai UI
Author by

Shai UI

front-end developer in finance. especially html5/javascript/css based apps for mobile/desktop/tablets, node.js on the back-end. my main interests are heavy GUI, 2d/3d, data visualizations. check out my youtube channel: https://www.youtube.com/channel/UCJagBFh6ClHpZ2_EI5a3WlQ

Updated on April 13, 2021

Comments

  • Shai UI
    Shai UI about 3 years

    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?