Simple example:
I have VM with hierarchical item structure and I have designed View containing TreeView. Each tree node corresponds to data item related to the one in the Model.
GUI must respect user preferences and settings and store different parameters including whether each particular node is expanded or not. As long as every node relates to some data we need to tie View settings with the Model. I beleive it's not OK to define property IsExpanded in the class standing for the Model.
So where should I store the settings so they stayed consistent with the data?
I believe it's not OK to define property IsExpaned in the class standing for the Model.
Why? Will there be occassions when the model is linked to two different tree-views?
If that is the case you can certainly create an "adapter view-model" that wraps your models and adds the property. Just be careful because that can technique can easily lead to a memory leak.
Otherwise, it is perfectly acceptable to put it right in the model, especially if that model is being used specifically to serve that view. As with all things, start with the simplest, most pragmatic approach.
I was in a similar situation, here's what I did to solve it.
Each ViewModel node had an IsExpanded property, which was bound to the TreeViewItem's IsExpanded property. I didn't want to persist the state of the tree by storing it in the Model in IsExpanded properties (it's to do with visual state right?). So instead, I had the VM tree structure generate a dictionary that stored the expansion state for each node against a string key generated from the node's state in the tree:
Dictionary<string, bool> treeExpandedStates
Each node in the tree had an ID, so in my case the key was something like "/1/3/7", but anything unique will do. This Dictionary was then serialized to a file on application close (in actual fact it was a SerializableDictionary). Then on application restart, it was deserialized and used to set the expansion state after the hierarchy had been loaded back up. This meant that the state of the tree was exactly as the user had left it, but nothing was stored in the Model.
I recognize the problem as a common dilemma in MVVM. I can look at it from two sides.
Approach A)
In the separation of View, Model, and ViewModel, what you describe resides in the Model. You write for example that it needs to be stored. That does not mean it is the same part of the model as the other model data.
Consider the following separation:
FolderModel - A model of the content or properties of a folder.
TreeNodeModel - A model of a users choices when exploring the tree view.
It might not be that easy to do a separation just like that, but the point is that MVVM is not meant to force you to stuff everything in the same place, and I do not think MVVM prevents you from keeping models for user interactions, the same way as you keep models for data content. Microsoft writes:
The data could come from a database, a Web service, a named pipe, a file on disk, or even carrier pigeons: it simply does not matter.
Why should not data for a data model be able to come from interactions of a user? :)
Approach B)
My usual approach to these dilemmas, though, is that properties like IsExpanded does mostly not need to be stored between sessions. That way, a property in the ViewModel, with a default value instead of a stored value, suffices. :)
And if it needs to be stored, it does not need to be stored in the Model. The ViewModel is for logic for presenting model data. If the ViewModel wants to save its logic state, that does not have to be stored in the Model.
Summary
In my point of view, you can store it any of these ways without breaking the MVVM pattern.
Related
My Desktop WPF application has a repository (of type Person) which resides in the Model layer, and is called by a ViewModel which has a PersonList property which is databound to a DataGrid.
When I open my Application, the list is shown by default. During initialization, the following code applies:
public class PersonScreenViewModel : ViewModelBase
{
PersonRepository _person_repository;
public ObservableCollection<Person> PersonList { get; set; }
public PersonScreenViewModel() {
_repositorio_pacientes = new RepositorioPacientes();
PersonList = new ObservableCollection<Person>(_person_repository.GetAll());
}
// ... ///
}
My doubts are based on some difficulty to understand how to implement "Save / Update" method(s).
Every text about the Repository pattern tells that "the repository should behave like a collection of [ entities | domain objects ]". So, the most logical thing would be to databind the repository itself to the DataGrid. That could be done if I created a class which inherit from ObservableCollection and implements repository logic. Currently, what I do is take a copy of the repository items, using _repo.GetAll(), and work in that copy, having to commit back after my changes are done.
Specifically, my workflow involves selecting a row in the DataGrid, changing some properties of the selected object, and commiting these changes, expecting that the same object is persisted with the new property values.
Usually, if you take an object in a collection and modify it, you don't need to "update" anything, since you already changed the object itself.
The question is: "How can I data bind my view to the repository itself? Should the repo inherit from ObservableCollection? How is it supposed to be done? Is some part of my reasoning flawed?"
It is important to say that my application is not data-oriented, the Person class is very basic (POCO marked as [Serializable], with a few properties), and my repository uses plain XML serialization and the filesystem structure.
Thanks for reading!
"Every text about the Repository pattern tells that "the repository should behave like a collection of [ entities | domain objects ".
What you originally have is sort of correct. First of all ObservableCollection works perfectly with the View because every add/update/delete will automatically propagate back to the user interface. If you implemented it with repository, then you would have to go call the database reload the control bound to your repository
"How can I data bind my view to the repository itself? Should the repo
inherit from ObservableCollection? How is it supposed to be done? Is
some part of my reasoning flawed?"
You don't want to data bind the Repository to the DataGrid itself, because you lose caching and every time the user loads the user control you always have a trip back to your database.
You don't want to inherit a repository to an ObservableCollection, ObservableCollection has more overhead vs simple IEnumerable given you already database returned you a collection already.
You always don't want ObservableCollection as your collection for your data because it is expensive. A simple enumerable of data is enough depending on your scenario (Read-only data).
In my personal opinion, what you are currently doing is correct... it is generally good practice to have some separation between the various layers of your application; Models, View Models, Views and DataAccess (sometimes combined into Models). Having said that, it really depends on your application... it might not be worth doing this on small applications as it adds a lot of code and time to set up and maintain.
However, the main reasons for providing this separation (called separation of concerns) is to enable unit tests to be able to test the individual layers without concerning the other layers. For example, if we wanted to write unit tests for our view models, we wouldn't want to test their functionality on the actual data objects in the database. If we have this separation (through the use of interfaces) then we can simply mock up data objects to use during these tests.
Another reason, although less common in practice, is to enable whole layers to be 'swapped out' without affecting the code in the other layers. Examples of this would include changing the database used in the application, or maybe changing the views from a desktop application into web pages in a web application. If we have separate layers, then these changes won't affect the other layers.
So to answer your question directly, I wouldn't bind your views to the repositories at all... keep your current separation. After all, how long does it take to copy a collection sourced from the database into a view collection property?
UPDATE >>>
I'm not sure that I fully understand the question in your comment. I'm guessing that you are binding your PersonList property in your view model to the DataGrid.ItemsSource property to display the data. Any changes made in the DataGrid should affect the items in your PersonList. If you were to add a 'Save' Button, then you could update the database in that click or command handler.
If you were enquiring how to find out which elements had been changed, there are several methods for accomplishing this. There is a good tip in the How to get only modified Items from WPF Data Grid post here, but I prefer to use a duplicate collection and just compare them to find the changed elements (you'd need to implement the Equals method for this to work).
Please let me know if that does not answer your question.
In my WPF MVVM application my model is a complex tree of Model objects wich constantly changes at runtime. Model instances come and go at runtime, change their position within the tree and of course change their many properties. My View is almost a one-to-one visual representation of that tree. Every Model instance is in 80% of the cases also a node in the tree.
My question is now how I would design the ViewModel around this? My problem is that there are quite a lot of different Model types with each quite a lot of properties. If I understood MVVM corretcly the view should not communicate with the Model directly so this would mean that I would have to create a ViewModel type for each Model type and have to rewrap each property of the Model type in the ViewModel.
Also the ViewModel would need to "bind" to the propertychanges of the Model to pass it along to the view (using wpf datatbinding). I would need some factory that creates and introduces a ViewModel instance for each Model that appears anew and I would habe to dispose each ViewModel instance when the corresponding Model disappears. I end up keeping track of all instances I created. It is unbelievable how much bloat code is generated dues to this double wrapping.
Is this really a good approach? Each entity and each property more ore less exists twice and I have a lot of extra code keeping Model and View in sync. How do you handle this? Is there a more clever way to solve this?
Does anyone have a reference/sample implementation for this that does it better than I do?
I think you may run into trap of paradigm if you follow this path. MVVM is nothing more than a pattern, which simplifies development in WPF world. If it doesn't - don't use it or revise your approach. I wouldn't spend 80% of my time just to check the "Using MVVM" field.
Now back to your question. Correct me if I'm wrong, but it sounds like you are looking at MVVM from opposite direction: you don't need Model to ViewModel one-to-one correspondence. Usually you create ViewModels based on your View first, and only then on a Model.
Generally you look on a screen mockup from graphic designers, and create corresponding ViewModel, which takes all necessary fields from the Model, wraps/modify/format/combine them to make View development as easy as possible.
You said that your View is almost one-to-one visual representation of the Model. In this case it may have sense to create a very simple ViewModel which exposes root object of your model-tree, and let View consume model directly via that property. Then if you need some View customizations or commands processing you can delegate that to ViewModel.
Sorry for very vague answer. Maybe if you ask more specific question we could dispel the confusion :)...
I'm trying to get to grips with MVVM and so I've read a bunch of articles - most focus on the View -> ViewModel relationship and there's general agreement about what's what. The ViewModel -> Model relationship and what constitutes the Model gets less focus and there's disagreement. I'm confused and would like some help. For example, this article describes the Model as a business object whereas this article describes a class which manages business objects. Are either of these right or is it something else?
I think you are on the right track. The "model" is vague in a lot of cases because it is different things to other people, and rightly so.
For me, my business objects that come back from my WCF service I consider my model. Because of this my projects don't have that pretty file structure with the holy trinity of namespaces: *.Models, *.ViewModels, and *.Views. I personally consider objects coming back from business logic or anything of that nature the "model".
Some people tend to lump both the business objects and the business logic together and call that the "Model", but I find that a little confusing because I picture a Model to be sort of more static than I do business logic, but it's semantics.
So when you look at examples of MVVM projects and don't see anything very clearly "Model", it's just because folks treat them differently. Unless an application is very standalone, I would actually be very suspicious of an application with an actual *.Model namespace, to be honest.
The other thing that is great here is that many times you already have an investment in these types of business objects and I think a lot of people see "MVVM" and immediately assume they need to start defining the "M", even though what they already have is perfectly fine.
The confusion between a Model and a ViewModel is pretty common, too. Essentially I know I need a ViewModel if I need a combination of data and behavior. For example, I wouldn't expect INotifyPropertyChanged to be implemented on a Model, but I would a ViewModel.
From the other answers it should be obvious that the relationship between ViewModel and Model is somewhat fuzzy. Be aware that there is nothing stopping you from having ViewModel and Model in the same class, and when your requirements in a particular area are simple enough maybe this is all that you need!
How you structure the separation between ViewModel and Model will very much depend on the needs of the project or software that requires it, how demanding your deadlines are and how much you care about having a well structured and maintainable code base.
Separating ViewModel and Model is simply a way of structuring your code. There are many different ways of structuring your code, even within this pattern! It should be no surprise then that you will hear different approaches preached by different programmers. The main thing is that the separation can help to simplify and make reusable the independent portions of code. When you have cleanly separated business data, business logic and presentation logic you can easily mix, match and reuse your views, logic and data to create new UIs. The separated and simplified code is also often easier to understand, test, debug and maintain.
Obviously not everyone will agree with this answer. I think that is part of the inherent fuzziness of the problem. In general you need to consider and trade-off the advantages versus the costs of having a separation between ViewModel and Model and know that it is not always a simple task to decide what goes in the ViewModel and what goes in the Model. It will probably help to lay down some ground rules that you or your organisation will follow and then evolve your rules as you understand which level of separation best suits your problem domain.
I think it is worth mentioning that I used to use a similar approach to MVVM when programming Windows Forms and the fact the WPF has more direct support for this (in the form of data binding and commands) has really made my day.
There are a lot of different implementations and interpretations.
In my mind, however, the value of the ViewModel comes from coordination.
The Model is representative of business data. It encapsulates scalar information, as opposed to process.
The View is obviously the presentation of the model.
The ViewModel is a coordinator. In my opinion, the job of the view model is to coordinate between the view and the model. It should NOT contain business logic, but in fact interface with business services.
For example, if you have a view that is a list of widgets, and the widgets are grabbed from a service, then I'd posit:
The Model is a List<Widget>
The View is a ListBox bound to the ViewModel property Widgets
The ViewModel exposes the Widgets property. It also has a IWidgetService reference it can call to in order to get those Widgets.
In this case, the view is coordinating with a business object so the view doesn't have to know anything about it. The model should be ignorant of view models, views, and every thing else ... they should exist independent of how they are used. The IWidgetService would get bound to the view model using some source of dependency injection container, either constructor injection with Unity or an import using MEF, etc.
Hope that makes sense ... don't overload your viewmodel. Think of it as a coordinator that understands business objects and the model, but has no knowledge of the view or how business process is performed.
The value added by the model is its decoupling from the ViewModel and the View. Think if you had to construct and maintain business logic in the ViewModel you would have lots of duplicate code.
For instance - if you had a car game with a GearBoxView (a control in the CockpitView), CarViewModel and CarModel - the advantage of abstracting what is in the CarModel from the CarViewModel is that the CarModel can be used in the WorldViewModel and any other ViewModel. The CarModel can have relationships with other Models (GearsModel, WheelModel, etc).
Your question specifically asked about using a Model as a business object or to manage business objects: my answer is it can do both - and should be responsible for both.
Heres an example
public class WorldModel //Is a business object (aka game object)
{
private List<CarModel> _cars;
public List<CarModel> Cars
{
get //Here's some management of other business objects
{
//hits NetworkIO in a multiplayer game
if(_cars == null)
{
_cars = myExternalDataSource.GetCarsInMyGame();
}
return _cars;
}
}
public Level CurrentRaceCourse { get; set; }
public CourseTime TimeElapsed { get; set; }
}
I think of the model as something that contains the smallest units of business entities. The entities in the model are used not only across the view models in my application but even across applications. So one model provides for many applications and, for those applications using MVVM, many view models.
The view model is an arbitrary collection of entities from the model that are brought together to serve whatever the view needs. If a view requires 2 of these and 1 of those, then its view model provisions them from the model. Generally, I have 1 view model per view.
So a model is like a grocery store. A view model is like a shopping cart. And a view is like a household.
Each household has unique requirements. And each household has its own shopping cart that cherry picks what the household needs from the grocery store.
My thoughts
(The "Model")
Have one model. Just data no methods (except if apt for the platform some -simple- getters/setters).
(The "View Model")
To my mind the rationale for a view model is:
(1) to provide a lower-RAM-requirement backup copy of fields so views hidden behind other views can be unloaded and reloaded (to conserve RAM until they reappear from behind views covering them). Obviously this is a general concept that may not be useful or worthwhile to your app.
(2) in apps with more complex data models, it is less work to lay out all application fields in a view model than to create one reduced model corresponding to the fields of each possible data change, and easier to maintain, and often not significantly slower performance wise.
If neither of these apply, use of a view model is inapt in my view.
If view models are apt, have a one to one relationship of view models to views.
It may be important to note/remind/point out that with a lot of UI toolkits if the exact same "String" object is referenced twice (both in the model and the view model) then the memory used by the String object itself is not double, it is only a little more (enough to store an extra reference to the String).
(The "View")
The only code in the view should be (the required) to show/hide/rearrange/populate controls for initial view load and (when user is scrolling or clicking show/hide detail buttons etc) showing/hiding parts of the view, and to pass any more significant events to the "rest" of the code. If any text formatting or drawing or similar is required, the view should call the "rest" of the code to do that dirty work.
(The "View Model" revisited)
If the (...facts of which views are showing and...) the values of view fields are to be persistent ie survive app shutdown/restart, the view model is part of the model :--: otherwise it is not.
(The "View" revisited)
The view ensures that the view model is as synch'ed with the view in terms of field changes as is appropriate, which may be very synched (on each character change in a text field) or for example only upon initial form population or when user clicks some "Go" button or requests app shutdown.
(The "Rest")
App start event: Populate the model from SQL/network/files/whatever. If view model persistent, construct views attached to view models, otherwise create initial view model(s) and create initial views attached to them.
On commit after user transaction or on app shutdown event: Send model to SQL/networkl/files/whatever.
Allow the user to ("effectively") edit the view model through the view (whether you should update the view model on the minutest change of a character in a text field or only when the user clicks some "Go" button depends on the particular app you are writing and what is easiest in the UI toolkit you are using).
On some application event: the event handlers look at the data in the view model (new data from the user), update the model as required, create/delete views and view models as required, flush the model / view models as required (to conserve RAM).
When new view must be shown: Populate each viewmodel from the model just after the viewmodel is created. Then create view attached to view model.
(Related issue: what if any data set primarily for display (not editing) should not be entirely loaded into RAM?)
For sets of objects that should not be entirely held in RAM cause of RAM use considerations, create an abstract interface to access information on the overall count of objects and also to access the objects one at a time.
The interface and its "interface consumer" may have to deal with the number of objects being unknown/estimated and/or changing depending on the API source providing the objects. This interface can be the same for the model and the view model.
(Related issue: what if any data set primarily for editing should not be entirely loaded into RAM?)
Use a custom paging system through a slightly different interface. Support modified bits for fields and deleted nits for objects - these kept in the object. Page unused data out to disk. Use encryption if necessary. When editing of set done, iterate it (loading in pages at a time - one page can be say 100 objects) and write all data or only changes in transaction or batch as appropriate.
(Conceptual significance of MVVM?)
Clean platform-agnostic way to allow and lose data changes in views without corrupting model; and to allow only validated data through to the model which remains as the "master" sanitised version of data.
Crucial to understanding the why is that flows from view model to model are conditional on data validation of user input whereas flows in the opposite direction from model to view model are not.
The separation is achieved by placing code that knows about all three (M/V/VM) into a core object responsible for handling application events including startup and shutdown at a high level. This code necessarily references individual fields as well as objects. If it didn't I don't think easy separation of the other objects can be achieved.
In response to your original question, it is a question of degree of interrelationships of validation rules on update of fields in the model.
Models are flat where they can be but with references to submodels, directly for one-to-one relationships or through arrays or other container objects for one-to-many relationships.
If the complexity of validation rules is such that merely validating a successful user form fill or incoming message against a list of field regular expressions and numeric ranges (and checking any objects against a cached or specially fetched copy of relevant reference objects and/or keys) is enough to guarantee that updates to business objects will be 'with integrity', and the rules are tested by the application as part of the event handler, then the model can just have simple getters and setters.
The application may perhaps (best) do this directly in-line in event handlers where the number of rules is so simple.
In some cases it may be better even to put these simple rules in the setters on the model but this validation overhead is then incurred on database load unless you have extra functions for setting without validate. So for simpler data models I tend to keep the validation in application event handlers to avoid writing these extra setters.
But if the rules are more complex either:
(a) a single method taking a special object that is really a composite of the usual business objects containing data for myriad field changes is written for each complex model change, and the method can succeed or fail depending on validation of the rules - facade pattern;
or
(b) a "dry run" / hypothesis / "trial" copy of the model or a subset of the model is created first, setting one property at a time, and then a validation routine run on the copy. If validation is successful, the changes are assimilated into the main model otherwise the data is discarded and an error raised.
The simple getter/setter approach is in my view preferred when analysing each individual transaction unless the vast majority of updates for your app are complex, in which case one can use the facade pattern throughout.
The other way the model ends up getting more complex than a bunch of fields with (possibly) simple getters/setters is if you start "enhancing" classes' getters/setters (with an O2R mapper tool), or adding extra aspects like calls to transaction monitoring APIs, security APIs (to check permissions, for logging etc), accounting APIs, methods that pre-fetch any related data needed for a get or set, or whatever upon get or set. See "aspect-oriented programming" for an exposition on this area.
My concept for MVVM in WPF is that we have a ViewModel for every Model in your application. This means that if we have Customer class (entity) then we will have CustomerViewModel. The CustomerViewModel will have all the properties which are necessary to represent a customer. The CustomerView usercontrol will be responsible for creating the UI for the Customer model.
Now, let's say that we are adding a new customer. So, we have a form which consists of FirstName, LastName etc. Do we need a ViewModel for this scenario. I mean all I have to do is to take all the input values from TextBox and create a Customer object and then save it to the database. Why should I bother creating a ViewModel for this scenario?
First of all, that is not the main purpose of MVVM, to "mirror" everything. The View should provide the means for a user input, and certainly not process calls to any of the database layers. The ViewModel should be a GUI-agnostic application backbone, and it definetly should handle the creating of customers.
That said, what you should do, is have a ViewModel which represents a workspace for handling customers, and not just a customer ViewModel. If you really want to save on a few objects being created, add to that workspace the possibility to create and add a new customer (not CustomerViewModel). That way, you can have a View of the workspace which has elements for each relevant/required property of the customer, and by invoking some command added to that workspace ViewModel, you could get the current values filled in those (data bound to ViewModel) View elements directly to the customer model.
Consider if you could probably drop the specific customer (and other Model) ViewModels if you refactor things a bit, it would be good practice to keep things from adhering blindly to a certain pattern without explicit cause.
Let's pretend for a second that there is no business model. The only thing you have is a view. If you were to model just that view, without any knowledge of what the data means elsewhere in the system, that is a ViewModel.
The goal of a ViewModel is to, well, model the view it backs. This is a different goal than modeling the idea of a customer in your business domain. To say you will have have one ViewModel per business entity, then, is to say you will have one view per business entity, which leads to run-of-the-mill data-focused UI.
In your particular case, think about the customer edit view. It has fields that correspond to a customer's properties, and thus seems like a natural fit for binding to a customer directly. However, where on the customer object is the "Submit" action modeled? Where is the "Cancel" action modeled? Where is it modeled that field X is an enumerated value selected from a list?
How about the password? If persisted as a binary hashed value, does the view know how to hash its text? What if the system has password strength requirements?
The ViewModel is the mortar between the business model and the UI. It takes concerns from one and translates them into terms of the other. It is the point at which all the above issues are addressed. To say a ViewModel isn't necessary is to ignore its necessity.
You don't need to have a separate ViewModel for Add, you only need a single ViewModel which should do Edit and Add scenarios. If you can delete the record from the edit page than that ViewModel should also have the ability to delete. Your ViewModel should reflect the functionality your View exposes regardless of data.
I think you should reconsider having a single ViewModel for each model. I like to think of ViewModels as normalizing behavior inserted of data. By having a ViewModel for each Model class you will run into architecture issues sooner or later. I look at the application from top down overview, what is my UI trying to accomplish and from there I will get to the ViewModel and eventually I will get to my DataFactory and how the ViewModel maps down to data is almost always not 1 to 1 except for the most simplistic Views. If you try to map 1 to 1 you will have bad UI or your data will not be normalized very well.
The Stack we have here is:
View
ViewModel (Controls everything the user can do in the view, wraps properties from our POCO's)
DataFactory (Maps our POCO's to Entity Framework objects and CRUD)
POCO's (Business Logic, all rules and validation)
Entity Framework (Model, Data Access)
One note here is that ViewModel contains properties from multiple POCO's!
We inject the DataFactory through StructureMap and Unit test with xUnit along with Moq.
To answer you second question I would create a separate view only view to drop in as a user control. But you should still have a CRUD ViewModel in you app that encapsulate all that functionality in a user friendly way.
Thanks.
One reason for this VM abstraction is for testability. Another reason why you want a ViewModel is because it's basically a Data Transfer Object that might be a combination of fields from multiple models in a single container that is more relevant to your current view. Yet another reason to have VM is to take advantage of WPF two ways binding capabilities.
Using your regular model (plain POCO), you can update the View when your model change, but since your model does not implement dependency properties (most likely), you won't be able to take advantage of updating your model when the value in WPF control changes. Which mean you have to manual add a handler and do the copy this value from this control back to the model kind of thing.
I can't quite figure out how to get the view model to be notified of changes in the model without adding a bunch of UI specific stuff like INotifyProperyChanged and INotifyCollectionChanged in my model or create tons of different events and do a bunch of things that feel like they're UI specific and should stay out of the model.
Otherwise I'd just have to duplicate all the business logic in the view-model to make sure everything is up to date, and then what's the point of having the model then?
One of the tricky ones that I have in my model is a property of a "Category" class. You can think of it as a tree structure and the property is all leaf-node descendants. Well in the model that property is generated on the fly recursively through all it's children, which is all fine and good. The view-model however needs to bind to that property and needs to know when it changes. Should I just change the model to accommodate the view-model? If I do then the view-model doesn't really do anything at this point, the model raises all the necessary notifications of changes and the view can just bind straight to the model. Also if the model was something I didn't have the source to, how would I get around this?
I disagree that INotifyPropertyChanged and INotifyCollectionChanged are UI-specific. They are in namespaces and assemblies that are not tied to any particular UI stack. For that reason, I typically put that kind of behavior as low in the system as I can (usually the data layer).
If there's some reason you don't want to put it at that level, that's fine. You can put it in at a higher level such as the service or UI layer. However, you need to make sure all changes to the data structures occur through that layer also.