I know that in MVVM, we want to propagate user input from the view to the view model via data binding, and give the reflected view state in the view model to the model, where we write the business logic code, and update the user with the result via events.
However, does it mean that every change in the view must be done outside of the xaml.cs file?
Take for example a WPF application for sliding puzzle:
If we want to write an algorithm to solve the puzzle, we'll put the code in the model.
However, assume we want to update the grid after the user clicked the down key.
Checking if such move is possible, redrawing the board or giving the player any feedback (if the move is legit or no) should be done in the view? (the xaml.cs file)
More generally, are there "rules of thumb" to decide what to handle where?
Quick recap for the MVVM layers (or "rules of thumb"):
Model: Contains only the data used by the view models. As an exemple, consider business objects coming from database as "models".
View: Connection between the user and the view model. You can use multiple views for a same view model. If the view model changes and updates, the view should show the changes.
ViewModel: Contains the "business logic" between the view and the model. As such, commands, possible actions and algorithms are stored here. The view model dictates what is possible and what is not.
The communication between layers needs (that's the part necessary for MVVM) to be interchangeable, meaning the view model can be used with differents compatibles views and the model can be used by differents compatibles view models. To cut down on the dependencies of the multiples layers: the layers should not communicate directly between them. We use commands, events and direct bindings.
However, does it mean that every change in the view must be done outside of the xaml.cs file? [...] However, assume we want to update the grid after the user clicked the down key. Checking if such move is possible, redrawing the board or giving the player any feedback (if the move is legit or no) should be done in the view? (the xaml.cs file)
No. The view model should explicitly tell the view what is possible and what is not. The view shows that the action is possible or not: it does not decide if it is possible. Such decision is in the business logic, so in the view model.
As a trail of thoughts, take what it is said about interchangeable views. If you switch out the view foo for another view bar to show your puzzle and you did put the decision about "what's possible" in the view, you will have to rewrite the decision tree/algorithm in the new view bar and thus, duplication of code/logic.
When the decision is higher up, the view reflects what the view model is telling him. If the view model wants the view to "refresh" or to tell the user "hey, that's an illegal move", the view model will do so via commands and events. After receiving such events, the view could then decide what to do with it:
Show an error message about the illegal move
Show a tooltip that the move is illegal
Flash and shake the window with a beep to show that the move is illegal
Many more implementations...
I do hope I answered your question as thoroughly as possible.
My 10 cents:
If my experience have taught me anything, it's that it's almost impossible to fit all problems with the same, general solution.
In the case of MVVM, some things I've learned (the hard way):
It's easy for the view model to devolve into God classes (ie, mix of purely view-related logic + some business logic + etc..)
Depending on the application tiers, some times it makes sense for logic to work on view models; other times, it's better for logic to work on the models instead.
Whatever layers I/you/anyone think certain classes/logic should go, will most likely have to change as development progresses.
Instead, my approach is usually:
Prepare
Model (for serialization, very little logic),
View Model (with property change bindings for view) and
View (thin layer, binds almost directly to View Model)
Write the majority of the application logic in the View Model.
Easier to have logic in here, so view bindings can work
This is the stage where the View Model layer bloats up
When the application is finally working, begin refactoring
For rich-client applications, I find my Model classes to be almost purely data
The View Model will most likely be refactored into 2 layers: MVM (Model-View-Model) and VVM (View-View Model)
MVM: This is where common, business-related logic/objects sit
MVM Objects contain truly common properties that any view can bind to
VVM: This is almost a 1-to-1 replication of a WPF view
These objects are typically never shared outside its own view
The separation into MVM and VVM helps prevent a single view model class from catering to ever views' needs (ie. whole bunch of Is(Selected|Checked|etc) and *Command, that may be only used exclusively by one view).
(For some people, VVM logic could probably be part of the View. But for me, I often find myself eventually wishing I had separated them in the first place, for testing. So now I do.)
As the application evolves, properties/methods can be either pushed from the MVM into the VVM, or vice versa.
The application's hierarchy is almost never truly static.
Even when you build the best version of the application possible, the client will simply want more.
Having the know-how to refactor an existing architecture to accommodate new requirements > Designing an architecture that is flexible enough for any future requirements
having said all that, for many applications that aren't too complex, a slightly-bulgy View Model is usually good enough.
Related
In learning Xamarin.Forms/UWP/WPF tutorials always tout MVVM as the design pattern of choice and I've followed suite, but I've never understood why. To contrast, in asp.net MVC the templated framework is used to great effect, Controllers deliver models to the view (HTML of some sort).
But in the Xamarin.Forms/UWP/WPF and others, we create a completely new class, ignore the code-behind file that cannot be removed and relegate it to telling our view where to look when binding data.
The only reason I could think of that makes MVVM better is if we could supply logic where different VM's could be 'injected' into the same view, maybe that would justify it.Though I have no idea how to do that.
Otherwise, how is creating a view model class better than using the code behind file? Is it really worse separation of concerns just because the view and code behind have the same name and are instantiated together?
MVVM pattern is much cleaner than using code-behind.
Separation of concerns
Imagine you have a view and a code-behind implemented. Now the business comes with a request to completely change the way the controls are presented - replacing them with new controls, changing layout and so on. Chances are, you will be forced to rewrite a lot of code just to satisfy the requirement, because the code-behind is directly tied to the view.
Now in case you have MVVM in place, you can easily swap the View part of the equation for any view which utilizes data binding to the right properties in a View model. You could easily present a single View model in several different ways - like creating multiple different views for different user roles while the view model stays exactly the same, you just choose what to display and how.
What view model actually creates is a middle layer between data and their presentation and makes it possible to more easily transform the data the view uses and change the presentation without affecting the view model if the interface is kept intact.
Data binding
Also if you are meaning purely code-behind without data-binding, the advantages of MVVM become even clearer. When you have a data-bound property that updates after user input in a TwoWay manner, for example if you have a form the user has to fill out, you don't have to remember to fetch the latest "changes" from the control using Text property, you know the latest version is already there in the data-bound property. In addition, you can add validation in the property setter, you can update other properties in the setter as well to orchestrate data handling in a much more abstract way than with code-behind approach, where you are tied to events and having to remember where the data come from and which specific controls and which specific properties you have to update. Imagine you display a given text in multiple places - with data binding you just set a single property and rely on {Binding} to display the text in all bound controls. With code-behind only, you need to remember which concrete controls display the text and when you add a new control, you have to update the code-behind appropriately, which is far less convenient.
Cross platform development
Another example would be having to develop a cross-platform application with native UI using MvvmCross. Here you can decide that some views or some functionality will not be available for certain OS or that you want to just implement it later. This is entirely possible - you just don't provide the UI for that functionality and the view model can stay the same.
View state
Finally - having all view state in code-behind means that when you navigate away, you must store the state somehow and restore it when navigating back because a new page is created. With MVVM you may decide to keep the view models of the navigation stack in memory and when navigating back just set the DataContext of the page to the existing view model instance to get back just in the same state as you left off.
Overall I see MVVM as a great pattern to improve flexibility of your codebase and it makes your solution more future-proof and resilient to changes.
I am trying to understand the MVVM pattern and there is some issue that is not clear. My Xamarin Forms application will have several Views (which is quite obvious). Must everyone of them be binded to different ModelView class? Or maybe there should be only one MV?
Yes and No
Yes -> Basically the idea is that your ViewModel should only be used by one view. If you use a ViewModel to populate an area or whatever then that ViewModel is "reused" each time that view is presented in difference places.
No -> You can use multiple models in a view model. The purpose of the view model is to abstract away the business / data layer (i.e. the model).
However, using more than one model usually indicates that the view is too large. You might want to split it into user controls (which have their own view models).
References:
With MVVM, does each UI window have its own ViewModel?
In MVVM, is every ViewModel coupled to just one Model?
I've always thought of "each View has its own VM" - the model as being a sub-set of a comprehensive design.
I will say from painful experience: do not design models in isolation based solely on the view/UI they support. Without a comprehensive model back end you will have a hard time integrating all of the pieces into a coherent, complete business model that works. Anemic classes, redundant bits, incomplete and wrong validations, same properties-different names, incompatibilities w/ existing code, gobs of hacky glue code, Programmers breaking each other's code, no re-usability, no reuse of existing classes. For us it all came to a head in a 3 month test-fail-fix tilt-a-whirl of embarrassment.
I've been using MVVM for a while now with WPF. And i've learnt a lot over the course of development (going from never using it, to having a couple of applications developed in it)
However, recently I had some comments directed at the code which made me wonder if i'm doing things the right way. My current setup works (roughly) like this:
Model - Responsible for storing the data, data validation using
IDataErrorInfo and dirty tracking
ViewModel - Responsible for getting the data (from a repository like
pattern) and formatting it for a view's consumption (things like
filtering, ordering) also responsible for command handling from the
view (save, load, filter changes etc)
View - The usual UI stuff
Now it was mentioned to me that i should NEVER have business logic inside the model, and that the model should be as thin as possible, the viewmodel should be responsible for handling things such as data validation and dirty tracking.
I've seen comments and criticism on both sides of this, with people against and for putting logic in the model, What i have yet to see is any actual reasons for these sweeping statements. So id love to know if there is an actual reason i should be refactoring my setup.
Also, given that i do move the logic to the viewmodel, I can see the need for having multiple viewmodels where i currently have a single, for example:
Person - Model
PersonViewModel - Handles the dirty tracking, data validation etc
PersonsViewModel - Handles getting a collection of PersonViewModels,
filtering etc
PersonsView - The UI
This seems a little redundant, but perhaps i'm misunderstanding something. What I'm really looking for is some actual reasons for doing this one way or another, or if this is another argument like the use of code-behind in MVVM (pure opinion with little reasons etc)
High level description of MVVM:
View: User Interface
Model: Business logic and data (e.g Domain Model+Repositories, or Transaction Script+POCO entities, etc)
ViewModel: Data exposted to view in such form, that is easily consumable from view. Wikipedia's definition says: The view model is an abstraction of the view that exposes public properties and commands.
I like the Practical MVVM Manifesto (archived version) principes: Simplicity, Blendability, Designability, Testability.
This is very high level and abstract description and that's why you may find a lot of variations of MVVM. Whatever mvvm style you choose, keep in mind the responsibilities and principles and you should be ok. Try to avoid complexity. MVVM is not a silverbullet and you cannot cover all scenarios with single design pattern. One mvvm implementation may be suitable for one application but not for another. I, for example, build my mvvm architecture from scratch for each new project to ensure the best fit
When is comes to responsibilities:
Take validation as an example:
validation logic that password and repeat password inputs should be equal is clearly presentation logic and should be present in viewmodel. On the other side, there may be business rule, that password must contain at least one special character. This logic should reside in Model, however you may expose it in viewmodel to be easily consumable from view. It's a business logic, but you may need to present it somehow.
if you have application that only uses webservice to retrieve and store then your model will be probably just the data access components.
Here is couple of resources:
Wikipedia: https://en.wikipedia.org/wiki/Model_View_ViewModel.
MVVM is variation of Martin Fowler's MVP pattern, you may find it useful as well: http://martinfowler.com/eaaDev/PresentationModel.html
MSDN (Pattern and practices): https://msdn.microsoft.com/en-us/library/hh848246.aspx
I like to think of the Model layer as anything that has nothing to do with how the app is hosted (i.e. independent of WPF). It is one or more dlls that represent the business domain and the operations that need to be performed in it. If it would make sense to take theses same dlls and use them in a web application, windows service e.t.c then it is usually a sign that the split between Model and ViewModel is appropriate.
There's no simple answer to your question. The simplest answer is that the model and view model should contain the code that you should unit test. The separation between model and view model is a little less distinct. I like to keep the model as simple as possible and limit it to whatever is exchanged with the server tier. The view model should encapsulate the model, and provide any addition functionality (both business logic and abstract presentation logic) so that you can keep the presentation layer as simple as possible (declarative, in the case of WPF XAML).
I see it this way:
Model - Object that can be passed around. A Common type between different layers for communication.
ViewModel - Specifically created for Views. This should contain UI logic, for example, Data Annotations etc will go here. You might also call your web service methods here (assuming your actual business logic sits in a facade layer, or your database logic sits in a different layer/project) to populate the Views, dropdowns etc. You might end up with multiples of these per view, depending on your design.
View - UI Only.
I am not afraid to put external calls in the ViewModel
I'm trying to learn MVVM and WPF and I'm using the MVVM Light Toolkit. Here's what I'm not fully understanding and maybe it's due to an incorrect architecture of my UI.
What I'm trying to accomplish is pretty simple actually. This is a utility application by the way. I want a window that serves as the 'controller' so-to-say that has a set of buttons. Each button should change the content of a frame. Example: one button loads a 'screen' ( or a 'view' if you will ) that allows the user to configure an 'Agency' which is a custom object. Another button loads a list of Users from the Agency that was in the first 'screen'. This 'Users' view needs to also be loaded in the same frame. In fact, as of right now, the window with all the buttons really is only responsible for loading the 'screens' in the frame. The meat of the application will be within all the separate 'screens'
What I am not understanding is 1) how to let each screen/view know about each other since one is dependent upon the other. It seems that in MVVM the ViewModel shouldn't know about anything. But in my case, I need to pass information around ( such as my Agency ).
If I can get some hints on what I need to look into, that would be great.
Thanks!
Some ideas that might connect some of the dots:
You'll most likely have one viewmodel per view ("screen").
Each viewmodel will contain all of the logic for its corresponding view
Viewmodels can and will know about the models (Agency, Users)
Viewmodels can communicate with each other via the Messenger in MVVM Light
Think of MVVM Light's Messenger as an "application-wide eventing system". When you send a message out from one view model, any other view model can be listening for that message/event and react to it as needed.
Does that help at all? Keep your thoughts coming and I'll keep commenting and I'm sure the community will as well :)
Few things:
each of your screens, should be separate view (eg. user control or new window - I suppose you've done that already)
every part of model (eg. Agency, User) you want to display in your application, should be wrapped with its dedicated view model
your views don't really need to know about each other; you can use commands or events on view models to get rid of those dependencies
view model only needs to know about one thing: model it's building on
it's good to think about view as really simple class, with one single responsibility of rendering content; no logic, no code behind (unless it's purely UI/display related) is something to follow
You can try to prepare your models first (if you haven't done that already), then make view models for them (thinking what properties of models you want to expose to views) and once that's ready, build your views basing on view models. Other way around is also viable option - pick whichever feels more natural to you.
One more thing: since you mentioned you can display several screens in one (I assume) main area, think about equipping your view models with something along the lines of bool IsCurrentlyActive property. This way, you can easily show/hide views with button clicks and still utilize binding mechanism.
They shouldn't know about each other. That is what the Messenger is for controllers and views subscribe to the events they are interested in. That way they don't need to know or care where they event originated.
Hmm Kendrick is faster. What he said.
Also it sounds like you kind of want an Outlook type interface, some navigation that loads other views. I had the same question a while ago. How to do Regions in WPF without Prism?
To better understand the MVVM pattern look at this article: WPF Apps With The Model-View-ViewModel Design Pattern
Also I advice you to look at Caliburn Micro framework.
I understand the general reason why the Model-View-Presenter pattern is a good pattern. It separates the concern so that the same parts of code that deal with presenting information to the user do not worry about calculations, etc. My quesion is why do we need a view that essentially does nothing? All the view does is tell the presenter to do work and get the result back from the presenter. For example, in my C# views, I often just have a bunch of event handlers that call delegates that are implemented in the presenter. Why not just combine the view and the presenter? No concern is really separated because the view does not have any concern.
Two important advantages
We can write multiple views or replace views easily (for example WinForms => WPF implementation)
We increase the testability by creating test views for unit tests
Your View should simply be a way to get data to and from the user. Anything else that is not specifically related to that functionality should be pushed down into the Presenter (or model if it needs be). The presenter handles what the view gets but it should never be concerned with what view does once it gets it.
The presenter is an attempt to look at your "UI" in a more semantic manner. You may have 2 textboxes on your View but your Presenter sees Name and Surname. The idea should be that with the minimal amount of fuse you could lift the View off an pop another one on.
I don't know how much I agree with that and tend to prefer MVVM where you don't have Presenters, instead you have ViewModels which I feel are a better way to define the above abstraction.