MVVM - Reuse views with multiple view modes

I believe one of the main advantages of MVVM is decoupling, anchoring and lack of references makes things a lot more reusable.

All MVVM examples I find have a View with a ViewModel with the same name as they ExampleView

have ExampleViewModel

. And there is always a one-to-one relationship, one view, one ViewModel.

But in my current project I have a form to fill out, so data can be added to the database, and also the user can edit data in the database, so this View form can be used transparently with two different ViewModels, one to add data and one to data editing. It seems to me that this is a bit silly to copy and paste, and the whole view is just for it to be named after the ViewModel, and not only that, if I need to change something, it will always be twice as big and everything can be forgotten.

Some frameworks have a ViewModel locator that will use this same naming convention to automatically associate a View with a ViewModel, and this makes me question the reusability of Views with many different ViewModels.

My question is basically this: is there a problem in using the same View with different ViewModels? Is this bad practice? Are there any naming conventions in this particular situation?

The lack of examples of reusability makes me question the validity of this practice.

+1
wpf mvvm mvvm-light prism


source to share


3 answers


No problem - the view is aware of the view model, but not vice versa. It's okay with what you are doing.

However, I would create an interface for the common binding properties in both view models and then a view model locator to expose the instance as a property. This means that you bind to the implementation, but don't care which one.



How you switch this implementation depends on how you create your view.

+3


source to share


As the child's answer said:

Assuming NewExampleViewModel

both EditExampleViewModel

are using the same interface IExampleViewModel

(whose properties reference the view) and you strictly don't want to break encapsulation, you can do it like:

var view = new ExampleView();
...
var NewVM = new NewExampleViewModel(...);
...
view.DataContext = NewVM;
...
  (or)
var EditVM = new EditExampleViewModel(...);
view.DataContext = EditVM;
...

      

Note that you cannot use IExampleViewModel

both DesignInstance

in a view like:



<UserControl ...
    d:DataContext="{d:DesignInstance Type=vmi:IExampleViewModel}"

      

you need a specific type for this, so you don't have IDE support for defining bindings.

You can use NewExampleViewModel

or EditExampleViewModel

as DesignInstance

soon as you design a view to have IDE binding support, and then remove it for the encapsulation principle.

+2


source to share


Perhaps you should use user control instead of view.

Then you can embed custom controls into your views. User control is not designed to bind to a view model. It is designed to connect to other containers.

In your case, you have different ways of using this control depending on the state of your business model.

+1


source to share







All Articles