Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding Model to ViewModel (WPF)

I'm making the move from MVP to MVVM, and a little confused as to how best bind the ViewModel to the Model. I understand how we can leverage WPF's data binding infrastructure to route events between the View and ViewModel using ICommand and INotifyPropertyChanged interface, e.g., the View:

public class MyView
{
    public MyView()
    {
        InitializeComponent();
        DataContext = new MyViewModel();
    }
}

and the ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel(){}

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public ICommand MyCommand ... 
}

This works great!

Now, typically with MVP I'd have my Presenter hold a reference to the Model via constructor injection, and raise events on the Model from the Presenter to update data in the Model. I tried the same approach with MVVM, but this requires the ViewModel to take the Model as a dependency in its constructor, which seems to make things a little messy with MVVM when using it straight out of the box without some form of IOC (with WPF at least).

So, my two questions are:

  1. Is injecting the Model into the ViewModel the right approach, or should I be implementing INotifyPropertyChanged interface on the Model and making use of WPF's binding infrastructure?
  2. To reap the benefits of MVVM, should you almost always implement it with IOC and a DI container, or better still Prism?
like image 894
James B Avatar asked Apr 25 '15 18:04

James B


People also ask

How do I bind a view in WPF?

Now to bind the ViewModel(TaskViewModel in our case) and View(MainWindow. xaml) we have to write the below code. This is the code present in the MainWindow() constructor. The above code is setting the DataContext of the MainWindow as instance of the TaskViewModel.


1 Answers

  1. It is the "pure" MVVM approach: the View must depend only on the ViewModel. The ViewModel itself is a bridge between the View and Model.

    The motivation — definition and responsibilities of the Model, View and ViewModel and also their relationships:

    • The Model, which provides a view-independent representation of your business entities. The design of the model is optimized for the logical relationships and operations between your business entities, regardless of how the data is presented in the user interface.
    • The View class which is the user interface. It displays information to the user and fires events in response to user interactions.
    • The ViewModel class, which is the bridge between the view and the model. Each View class has a corresponding ViewModel class. The ViewModel retrieves data from the Model and manipulates it into the format required by the View. It notifies the View if the underlying data in the model is changed, and it updates the data in the Model in response to UI events from the View.

    -- Implementing the Model-View-ViewModel Pattern, MSDN.

    Conclusion. Injecting the Model into the ViewModel seems to be the right approach. Also, instead of injecting Model it can be useful to inject:

    • the Model Factory to create the Model — lazy initialization;
    • the Service (Service Facade) to retrieve the Model — lazy loading.
  2. As shown in the "MVVM Unleashed" book by Michael Brown, the following MVVM's potential benefits can be leveraged: maintainability, testability, "blendability", portability. At least, dependency injection (in the described case by using dependency injection container) allows a design to follow the Dependency Inversion Principle:

    The principle of dependency inversion is at the root of many of the benefits claimed for object-oriented technology. Its proper application is necessary for the creation of reusable frameworks. It is also critically important for the construction of code that is resilient to change. And, since the abstractions and details are all isolated from each other, the code is much easier to maintain.

    -- The Dependency Inversion Principle, Robert C. Martin, 1996.

    As a result, such MVVM's benefits as the maintainability and testability seem to be improved when the Dependency Inversion Principle is followed. Dependency injection container is just a tool to follow the Principle.

like image 199
Sergey Vyacheslavovich Brunov Avatar answered Oct 06 '22 04:10

Sergey Vyacheslavovich Brunov