WPF - MVVM: Duplicate all Models properties or expose the model - c#

I've to start a fresh application and I'm currently asking myself if there is some kind of best-pratice on how to bind our model to the view through the ViewModel.
Currently, I see two options:
My ViewModel duplicates every field that has to be bound to the View
My ViewModel expose a Model object instance, on which the different properties of the ViewModel bounds.
What I can see:
Duplicating the Model properties in the ViewModel
Advantages:
I keep a clear separation of concern between View and Model
I can implement here all the validation mechanism
Disadvantages:
It makes a LOT of code to duplicate(we create a new client for an existing solution, we have currently more than 1000 models)
More code to write = more to maintain = more errors
Exposing the Model properties in the ViewModel
Advantages:
The ViewModel will more focus on how to retrieve and save models
ViewModels are cleaner to read
This takes much less time to implement
Disadvantages:
Not sure that the model is the best place for the data validation
So, any guidance you could provide me, or way of having both of the two world would be greatly appreciated.

I wouldn't duplicate the values required in the view model, but it does depend on how the model looks and how you want the view to look. Create properties on the view model that wrap the model properties.

#j4n try to implement MODEL with INotifyPropertyChanged and try to wrap continents of Model in class so you can use observablecollection in it . Use of observablecollection reduce duplicate property

Related

Correct approach to MVVM

I'm trying to understand what's the best way to work with a viewmodel and with the model that stays behind.
My model is a collection of custom items (like a list of user configurations).
I understand that the correct way to expose this model is through a ConfigurationListViewModel that converts the model's list in data readable by the ui.
But how should I manage the items that lies behind the ConfigurationListViewModel?
Should the single configuration itself have a ConfigurationViewModel?
Or the main ConfigurationListViewModel should handle the exposure of its items?
If I want to add a Configuration to my ConfigurationList, I call an Add() method to my ConfigurationListViewModel, and it creates in itself a new Configuration, or should I create a new (Configuration? ConfigurationViewModel?) in the parent, and then call an Add([Configuration?ConfigurationViewModel?]newConf)?
Really, the answer is any of the above.
If the data used in the view model has a form identical to that of the model, you aren't doing yourself any favors by creating a ConfigurationViewModel class that is just a copy of the Configuration class.
As to adding, you can do it either way. Sometimes you want to do all your editing in the view model so you can "revert" the changes by not actually modifying the model. If that's not a concern, modifying the model first and propagating to the view model is just as valid of an approach.
All that being said, none of your approaches will violate MVVM. Pick what makes the most sense, especially semantically and for future maintenance. In general, I prefer simplicity to blind adherence to a principle such as "every data object needs a view model representation".
In my experience the ConfigurationListViewModel containing an ObservableCollection<ConfigurationViewModel> is the best (most flexible and cleanest) way.
Just for displaying selected items differently than non-selected items, it's useful when the items know about their selected state. And because selection is nothing the model should care about, you need a ConfigurationViewModel with an IsSelected property.
Updates (add, delete items) of the list (if triggered by the user/UI) should be done mainly by the model. (It's the model's responsibility to know how new item are initialized, for example.) And the ListViewModel should then change accordingly: create a viewmodel from the newly created model item or delete the viewmodel whose item was deleted in the model.

Should I have an encapsulating ViewModel for each Model?

I've been working with WPF and MVVM a lot lately. I was under the impression that I understood the MVVM pattern quite well but I've begun having some doubts.
Right now, I have an encapsulating ViewModel object for each Model object.
Let's say my Model contains two classes: Property, which contains a list of PropertyValue. In my ViewModel, I have a PropertyVm, which contains a Property and a list of PropertyValueVm (each containing a PropertyValue). Both Vm's implement a BaseVm which contains the OnPropertyChanged method.
Consider a View with two comboboxes, for Property and PropertyValue. The first combobox's ItemsSource will be bound to a collection of PropertyVms and the second combobox's ItemsSource will be bound to the PropertyValueVms of the PropertyVm selected in combobox 1.
This is all based on the article that got me to explore WPF and MVVM in the first place: Simplifying the WPF TreeView by Using the ViewModel Pattern, by Josh Smith
However, I'm becoming increasingly annoyed with the large amount of ViewModel classes my project contains, some of which contain very little code or simply nothing but the corresponding Model class.
Other implementations I've come across have the INotifyPropertyChanged on the Model objects instead. This would mean you'd assign the Model objects to the Comboboxes directly. This would slim down the amount of ViewModel classes, but doesn't this violate the basics of MVVM?
I've also seen people advocating a single ViewModel per View. But I fear this would turn my ViewModel classes into humongous, incoherent walls of texts.
So my question in short: Should I have an encapsulating ViewModel for each Model? If not, then what is best practice?
The primary driver of MVVM is to maximise the testable code via the strong separation of presentation and presentation logic. Ideally we encapsulate the presentation logic in one or more view models - so in terms of your sub-question, have as many view models as makes sense. Dividing the functionality up into a series of smaller view models is good practice from my experience. But there is no one-size-fits-all way to implement this. So in some ways, the answer to the question is: it depends on your situation.
If your model never changes then you've reached a religious fork in the road. The pragmatist exposes the model to UI binding (guilty!!). The purist wraps the model in a view model because the VM sits between M and V in the design and if we don't dogmatically adhere to this then bad things must surely happen.
If your model changes then you have design choices. You can keep the model immutable and refresh your view model with a new version of the model and raise changes from there. Or, if your architecture facilitates an ever updating model that the UI just needs to represent then ask yourself if you truly gain by sticking a view model in the middle. But!! As soon as you get a sniff of logic creeping into the model then it's worth a view model.

Should ViewModel have pass-through DependencyProperties that bind to DependencyProperties on the Model?

I am new to WPF/MVVM and the examples I have found do not seem to cover an issue I am facing.
I have a screen for managing a rather complex business configuration object. In MVVM I think this means I should have the following:
A XAML View with close to zero logic
A ViewModel class that has the screen logic
My usual business classes fill the role of Model and have all business logic
In my situation there are business rules that say changes to fieldA of my business class might have various side effects, for example changing the value of fieldB, or populating an entire list of sub-objects.
I could be wrong, but I think I should keep these rules encapsulated in the business class, as these rules are not really about the screen so much as the entity.
Naturally, these side-effects need to make their way back onto the screen immediately.
So from the user's perspective, he might edit fieldA, and see fieldB updated on the View.
I understand how to databind from the View to the ViewModel.
But in my case, it seems that I need two layers of databinding: one between the View and ViewModel, and another between the ViewModel and the Model.
Given that I have essentially the same problem twice, I think one solution should apply. So I have made my Model class into a DependencyObject, and I have made its properties into DependencyProperties.
Looking at fieldA for example, it would appear in all three layers:
View as a visual component databound to ViewModel.FieldA, for example text="{Binding FieldA, Mode=TwoWay}"
ViewModel as a DependencyProperty bound "upward" to the View, and "downward" to the Model
Model as a DependencyProperty
I prefer not to directly couple my View XAML to the business object by skipping part #2, this does not seem like a clean application of the pattern to me. Perhaps that is misguided.
I essentially seem to need a "pass-through DependencyProperty" in my ViewModel.
My questions:
Is this the right general approach or am I thinking about it all wrong?
Are there examples out there using this pass-through approach?
Can someone give a code example of the proper way to create a pass-through binding between the ViewModel and Model FieldA DependencyProperties?
I struggled with this issue myself, and I imagine it is a very common snag when it comes to MVVM. My answer was to avoid polluting the domain with DependencyObject or INotifyPropertyChanged as it somewhat negates the validity of using a ViewModel.
The goal of a ViewModel is to expose a model in a manner that is relevant to a particular view. It gets confusing when the VM essentially needs to expose an entire domain object. I refer to these as "Editor" view models. These are the most tempting to pass through properties from the domain object. In these cases I give the VM a reference to a domain object (composition) and pass through getters and setters. The ViewModel adopts INotifyPropertyChanged and IDataErrorInfo rather than DependencyProperty to signal the UI if the UI needs to refresh or display validation errors. If the domain raises a validation error, then the VM catches it and prepares it into the data error info details for the view.
I would agree with Steve that you should avoid using DependencyObject and DependencyProperty in your model/domain classes, and the view model classes should adopt INotifyPropertyChanged and IDataErrorInfo for binding purposes.
I would add that in your view model classes, I would avoid using DependencyProperty except for properties that you need to utilize in xaml logic, such as DataTriggers.
For handling changes that are triggered within a model layer class, I would also have a reference to the model/domain object in the view model class, and pass through getters and setters to the model/domain class just as Steve mentioned. I would add that the model/domain class will need to raise an event that the view model class will need to subscribe to, so that OnPropertyChanged() for one or more properties can be called in your view model class based on a change that happened in your business logic.
Firstly, I would not recommend using dependency properties (DP) for view models, or models. DPs are properties that have been designed with UI concepts in mind, such as precedence rules, DataContext support, default values and more. You do not need these concepts within a view models, so you should use INotifyPropertyChanged instead.
Having a view-model that is simply a pass-through to a model layer adds no value at all. So don't do it! You should never add layers, structures or concepts to your code just because you think you should. Simplicity is something that you should always strive for.
So, if you can implement a model layer, with INotifyPropertyChanged simply bind that to your view.
However ... in some cases you may not be able to implement INotifyPropertyChanged in your model. It might be generated from a web service for example. In this case you will need a view model that performs pass-through functionality, but also adds change notification via INotifyPropertyChanged.

How to get changes from the model into the modelview?

I'm currently busy with rewriting an application into MVVM (in stages, because it is a lot of work).
Currently I can fill listviews and controls depending on changes in the model view and also listview selections are coupled correctly (at least I know how I can do it correctly).
However, I was wondering about changes in the model to be reflected in the modelview (and thus in the view). Should I add INotifyPropertyChange interfaces on all items in the model and subscribe on the modelview (maybe even like a chain if I want to subscribe to an item that is not in the 'top' of the model hierarchy)?
E.g. I have a list A containing a list B etc. Do I need to subscribe in list A for property changes of list B and in the model view subscribe to list A? And unsubscribe if another list selection is made (resulting in a lot of unsubscribe and new subscribe items)?
Thanks for reading/answering.
Yes, typically you would implement INotifyPropertyChanged on your models, and subscribe in your view models. If you are using a framework such as CSLA for your business entities, then Rocky describes an anemic vs rich model, where in the later you expose the model directly to the view on your view model as a property.
I think INotifyPropertyChanged is a stable dependency, so it doesn't pollute your models significantly. Some people do not like exposing the model directly to the view, but I find it saves a lot or repeat code. You may find that if you don't, your view models end up duplicating many of the properties on your model, without adding any value.
If I understand right, you want to programmatically change your data in the model and show the updated data via the viewmodel accordingly?
I would suggest you change the viewmodel properties in your code instead and only use the models for loading/saving the data, that would eliminate that problem.

MVVM and where to keep displayed fields/properties

I am learning MVVM by building a simple WPF calculator app.
In this simple app, there is one view (Main window), one ViewModel, and one Model (the calculation engine).
My calculator displays the current value of all previous operations, and the operations that got to that value.
For example a display might look like this:
1 * 2 * 3
6
I am wondering if these should be saved as Properties on the ViewModel, Model, or both?
More general -- should the ViewModel contain only properties that exist on the Model, or this is not mandatory?
In this case i would save a CurrentValue and DisplayValue properties, just wondering which architecture layer should these belong to.
In MVVM, ViewModels allow you to shape multiple entities from one or more data models or sources into a single object, optimized for consumption and rendering by the view. The below image illustrates the concept of a ViewModel:
The purpose of a ViewModel is for the view to have a single object to render, alleviating the need for UI logic code in the view that would otherwise be necessary. This means the only responsibility, or concern, of the view is to render that single ViewModel object, aiding in a cleaner separation of concerns (SoC). Concerns are distinct aspects of the application that have a particular purpose (i.e., concern), and keeping these aspects apart means your application is more organized, and the code more focused. Putting data manipulation code in its own location away from the view and controller, enforces SoC.
Using ViewModels in MVNM for finer granularity and better SoC leads to more easily maintainable and testable code. Remember, unit testing is about testing small units.
I am wondering if these should be saved as Properties on the ViewModel, Model, or both?
In my opinion these should be property in ViewModel. Why these should be in the Model too? There is no benefit I can think of having this in Model too. These properties will only make sense to user in View so they should be displayed via ViewModel in the View. Model has nothing to do with it. At most you will have to pass expression 1 * 2 * 3 to Model and get results back, as you mentioned your engine is in Model.
More general -- should the ViewModel contain only properties that exist on the Model, or this is not mandatory?
In general, a ViewModel should contain all the properties that have to be displayed in the View (via ViewModel). Regardless of the fact whether this property exists in Model or not. There is no rule that if this exists in ViwModel it should must be in Model too and vice versa. Generally Model is nothing more than representation of your business entities.
First of all, the model is not the place, where all your logic should be. The model is just the data for the view.
View model should contain any code needed to correctly adapt the model data to WPF display.
In your case you should work on an architecture a bit more.
There should be a class like CalculatorProcessor. View model may have properties for CurrentExpression, that, when a button = is pressed, are passed to a CalculatorProcessor to get processed (calculated) in sequece.
A result is also a property on a view model class that a view's controls are bound to.
ViewModel is specifically created for databinding purposes and as you expected contains properties needed by the view. In my opinion if you need any computed values to be displayed in the view, you can expose them as properties on view model.
A model class is not only a business object, even if the model classes typically provide property and collection change notification events through change notification interfaces, so they can be data bound in the view, you can define an observable collection of instances of a class representing operations that represent he Ui interaction, so when a new op is inserted by the user, you add it to the collection and the UI will automatically reflect it through the binding to an templated listbox (for example)

Categories