What are the common relationships between Views, Models, and ViewModels? - silverlight

I'm working on a Windows Phone 7 app with a designer. I've done C# development with XNA so I know C# but was not familiar with the Model/View/ViewModel architecture.
Our first crack at it had multiple ViewModels active for any given view. Each ViewModel was an in-between layer for each object in our model.
For example: We had a "Friends" page that has a ListBox that displays the list of Friends. So we made a FriendsListViewModel that would handle getting an ObservableCollection<Friend> from the Model that the XAML would bind to. There were other functions available in the page (navigating to other pages, activating semi-related features, etc.) so that was contained in the FriendsPageViewModel.
This was starting to look crazy to me, so I made the relationship between View and ViewModel 1:1.
With all that described, I've got a question with two components:
With MVVM, what is the common relationship between Views and ViewModels? (focusing on Windows Phone 7 development here in case it's any different from ASP.NET, WPF, or Silverlight)
And as a possible addon to that question: Say the 1:1 relationship is the generally correct or accepted one: If you're dealing with something like a Pivot control or Panorama control, would you typically give each PivotItem or PanoramaItem its own ViewModel?

In MVVM, you typically have one ViewModel for each View (exceptions exist). The View typically 'binds' to the ViewModel which is the glue between the view and the data model. Your view can contain multiple controls and each control will bind to a particular property (i.e. data source) on your ViewModel. The ViewModel will then notify the View once one of these properties is updated (via the INotifyPropertyChanged interface in C#).
When thinking about ViewModels, don't think of it as a single ViewModel per control. Think of the control binding to a single property of the shared ViewModel.
The ViewModel provides data from the model to the View. The View should only be used to display the data it gets from the ViewModel. Keep code in the View to a mimimum and only pertaining to rendering control elements. The ViewModel is responsible for querying data from whatever the data source may be and then providing public properties the View can hook into.
This MSDN link has a pretty detailed article on it, but you can get a good synopsis on wikipedia.

Related

Is the Model in MVVM a Domain model or POCO?

Is it OK to use my Domain Model as Model in the MVVM pattern, in the context of a WPF application? Or is the Model (in MVVM) supposed to be some POCO? I personally don't see any reason against using the Domain Model as Model of the MVVM WPF pattern.
But then the XAML elements will bind to what? Properties in the VM, which underneath are mapped to the Domain Model, right?
To answer the question posed in your title: neither.
In MVVM, the "model" is generally everything the other side of the viewmodel (i.e. between the viewmodel and the repository). The model can (and usually is) composed of several different additional architectures and patterns, it is normal to have services, micro services, DALs and DILs, domain models, POCOs/data entities etc all within the "model".
The domain objects and POCOs you speak of are not the model, they are part of the model. The perspective of the model that you talk of has been brought over from other patterns like MVC, where a data entity or domain object is indeed the model. The model is a little more complex than that in MVVM.
You can bind directly to a POCO in MVVM, but it's not usually a good idea unless it is a very simple one that is not subject to change (like a lookup list that is sourced from a repository). And it is usually quite a bad idea to bind to domain objects because these will contain extra functionality or information that is related to storage and retrieval but is overkill for anything shown in the UI. The other problem with domain objects is they usually don't serialize nicely (if at all - often domain objects are generated), so unless you have a very simple model it is best to transform the domain objects to POCOs as soon as practical.
So as mentioned in the answer from Owen, you should wrap your POCOs with viewmodel classes before they are made available to the UI. The only time you shouldn't is when you don't need any property change notifications and you also don't want to leverage any further functionality on the objects (for example you won't need a context menu on the displayed item).
But then the XAML elements will bind to what? Properties in the VM, which underneath are mapped to the Domain Model, right?
Yes, you could reference your POCO model entity classes in your WPF application and wrap them in view model classes that implement the INotifyPropertyChanged interface to provide support for dynamic change notifications. This is perfectly fine.
Please refer to my answer to the below question for more information about this.
Correct way to update property in ViewModel from Model
You'll likely want to wrap your domain model objects with view models. The purpose of your view model is to expose data from your model in a way that is useful to the view. For very simple applications it might seem cumbersome to add that extra layer just for change notification, but as your application becomes more complex, having a view model layer to bind to can help keep your model clean. If you are doing something quick and dirty, there is nothing stopping you from binding directly to your domain model objects.
Yes as long as your domain model implements inotifypropertychanged you can use and bind xaml with VM properties

Prism and MVVM databinding from modules to main shell datacontext

Have some experience with WPF and databinding, but completely new to PRISM and MVVM.
I'm working on Prism application where I have a shell and multiple modules.
In my previous WPF application I had a single window datacontext (with all objects I need) which I could then simply databind from any usercontrol inside my window.
In the context of the Prism, what is the proper way to have a single datacontext, let's we call it ShellViewModel and then for all modules to bind to its' objects and properties? So if there is a change in one property in ShellViewModel which is caused by one module, another module can detected that by databinding and then maybe trigger a style?
Probably there is a simple way to do this but I'm new to PRISM and MVVM and completely confused how we can do properly bindings especially when there are multiple modules involved?
Also any source code and examples would be great.
If you have a single source of data, make it available to all your view models as a service.
Register it as a singleton, so that all view models get the same instance. If you need the service to push updates to the view models, make it implement INotifyPropertyChanged and let the view models observe that (done best through a PropertyObserver).
Remember that the view model is the data context of the view, and that it should only communicate data and events between the view and the data source a.k.a. model, but should not own data itself.

Ambiguous between Microsoft Sample and WPF Rules

I thought we should have no reference from View to ViewModel in MVVM Pattern. but just saw an MVVM Sample from code.msdn.microsoft in which ViewModel implements new Window and shows it;
By using MVVM-Light toolkit you use Messenger to Call or Open new Window and Still keep Separate the View and ViewModel form each other. Is it right to reference the View in ViewModel? Or it is wrong;
Do you suggest to call Views Directly from ViewModel for large(or medium) projects?
http://code.msdn.microsoft.com/windowsdesktop/Easy-MVVM-Examples-fb8c409f
YAGNI.
Level of effort and complexity.
MVVM is just a pattern. A pattern you don't have to follow. Any little tool I write for my own use just uses a model, a viewmodel, and a view. The viewmodel exposes all properties I need for the view by INotifyPropertyChanged. The data is moved back and forth from viewmodel to model manually using ViewModel.FromModel(model) syntax. I don't bind to my models. I only use the model when saving/loading data; I don't hang onto it. My views are generated using dataTemplates and dataTemplateSelectors. If I have a property that should change the layout I expose that on the viewmodel and use a selector. Otherwise, I have a datatemplate for every viewmodel object. And it just works.
I call this a form of MVVM, even though it doesn't any toolkit or the exact MVVM pattern that Microsoft describes.
I would personally implement a service to drive commands from the viewmodel to generate new views and hookup the viewmodel. But that's because I have MVC experience, and I think generating views is easier to do using the MVC pattern, whereas desktop views work better using the MVVM pattern.
All my views are composed with contentControls. Setting the content is setting the viewmodel.
So I use a hybrid.
If your software isn't so complex to need the complete Microsoft endorsed MVVM pattern, why create the overhead code IMO. YAGNI.
IMO, having a strong reference from the ViewModel to the View has 2 problems:
It breaks the testability of your ViewModel code. This means you won't be able to Unit Test your code so easily, and if you do you'll have to account for Dispatcher issues and the like.
It makes your ViewModels dependent on WPF assemblies and types. This means you won't be able to literally copy and paste your ViewModels into other applications or platforms such as Xamarin.Android or the like
If none of these are important to you, I don't see any reason why you wouldn't. Not doing so creates additional overhead in your code, by having to implement WindowManagers and whatnot.

Difference between View and Usercontrol when doing MVVM

lately i often see questions regarding MVVM and usercontrol, where - for me - view and usercontrol are mixed up.
for me a View when doing MVVM is just a pretty interface that allows users to interact with my ViewModels - so at least a collection of controls with Bindings. most time xaml only but codebehind not forbidden.
for me a usercontrol instead is not related to a viewmodel at all. the usercontrol has a representation in xaml and of course codebehind where properties, methods and Dependency Properties exist.
i'm on a wrong way with that?
EDIT: of course view and usercontrol inherit from UserControl class - so both technically UserControls. but i use just the term View when doing MVVM. and the term usercontrol just when there is no direct relation to a viewmodel.
ps: my english is too bad to write down what i mean...
You're not wrong just consider the fact the user control can be a reusable view that has a view model. cause the entire composite ui architecture is based on s shell(main window, view) and some regions with view (user controls)
A View and User Controls are totally different in MVVM.
The View is a conceptual name of the folder where you put all UI related stuff like user controls, windows, pages, etc. So the View is the folder that contains your GUI part for the particular application.
The User Control is the control which is configured by the developer by mixing multiple components / controls to work like a single control. A user control can also hold the other user controls.
The mix point is that, generally, views hold the user control in an MVVM application, as WPF is XAML based. It gets rendered in there, so the developer can plug your, his and other's user control into some where he wants to.
Whereas windows can not be placed into other windows. And pages can only be shown in frame element, so most views are user controls.

How should I implement multiple views on the same data?

I have a MVVM/WPF based application that can have multiple workspaces (basically containing a TreeView) open at the same time that display and operate on the same data tree. I need to be able to expand and collapse and select the items in each workspace independently and I want to be able to drag and drop items between the two workspaces (e.g. for moving or duplicating items). I also need data virtualization in that the data is only loaded (in both views) when a tree item is expanded for the first time. There is also one workspace-wide details view that shows the details of the selected item of the workspace that currently has the focus. Workspace specific expansion and selection of items must also work programatically.
Could you layout a ruff design for a MVVM based application that embraces theses features? Should I create a separate ViewModel tree for each workspace and implement a Model-ViewModel mapper? Or should I have just one ViewModel tree with two Views? How does the details view know what is currently selected and what workspace has the focus? ...
So to rephrase my question: The Model instances displayed in each View are actually the same instances. But should the ViewModels be the same too? Or better: Could I possibly get away with that?
Also: Is there an open source application I could study that has most of these features? Could Prism or any other MVVM based framework do most of that work for me?
There is a direct correlation between View and ViewModel. The View shows a visual representation of the Model, hosted and "formatted" by the ViewModel.
Since you will have different Model (data) on each View, you need to have several instances of your ViewModel hosting each set of different data.
Now the question is: do your ViewModels share some entities or objects between them ?
If yes, could they change during your application lifetime, and do you want to see these changes in realtime in your TreeViews ?
You then have two options:
Directly bind the model to the View (if the model implements INotifyPropertyChanged) by exposing it through your ViewModel: then all your views will be automatically updated when a model property changes.
Create a component which supervises Model modifications and notify ViewModel exposing them.
The second solution is more pure than the first one because Models should be POCO and shouldn't implement some plumbing oriented-interface. ViewModel should handle the plumbing.
However it's more complicated to design, and 90% of the time, you will end-up saying "come on, just one little interface doesn't hurt" :)
For your details view. You can communicate between your TreeViewModel and your DetailViewModel using a mediator (Messenger in the MVVM Light Toolkit), which is basically a low-coupled event-oriented component. Or use a supervisor which is injected in all your ViewModel and notify them using events.
Speaking of MVVM framework, and for common architecture like the one you are describing, I would recommend the MVVM Light Toolkit.
Maybe I am missing something, but is it not possible to have 2 instances of the same View / ViewModel loaded with different data?

Resources