How should I implement multiple views on the same data? - wpf

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?

Related

WPF MVVM two views, one view model

I am writing an application, which supposed to be running on 2 monitors,
when then small monitor displays the light version of the same information displayed on the large one.
What is the best way to implement this using MVVM model?
I have thought to create one view model and two views, and set the datacontext of those views to be the view model. Is it a right way to implement this ?
Thanks
I have thought to create one view model and two views, and set the
datacontext of those views to be the view model. Is it a right way to
implement this ?
As a comment a above stated, VM doesn't care about how it is used, so you can use 1 VM as View's DataContext as many as you want to.

How to architect graphically-intensive Silverlight app using MVVM?

I'd like to create a Silverlight app using WCF Ria Services and the MVVM design pattern.
The main page of the app will consist of a "shell" and a large number (10s or 100s) of objects of different look (shape/size/properties) linked to each other (forming a sort of graph).
These items need to be mouse-draggable and their current position/state needs to be saved to the back-end database.
I feel that the best way to achieve this would be to have a small ViewModel and View for each item displayed, put all the important properties into the ViewModel and then somehow display all these Views in the main "shell".
However, I don't know how exactly this could be achieved. I considered using MVVM Light, but didn't find any example that would show something similar.
Can anybody point me to some examples or ideas about how this could be done?
"When all you have is a hammer, everything looks like a nail" :)
MVVM is not designed to manage graphic intensive situation like the one you describe. It is a glue for stitching together high-level concepts in a flexible manner. With MVVM you are adding overheads that will impact performance (e.g. binding uses reflection behind the scenes). The more objects involved, the greater the impact.
The best starting point I can suggest is to imagine what you need from a 3rd party control (e.g. a custom control/container) and, if one does not actually exist already, build it as if it were a third party custom control.
You will find in practice that custom controls are seldom based on MVVM, for performance reasons if not just because "they often don't need it". They may well expose MVVM compatible properties for the external interface, but not for the low-level internals.
MVVM is a relatively high-level technique. Do not feel you have to implement it on everything.
Following MVVM do the next:
Model - create model object which will be responsible for fetching and persistence coordinates of the shapes on the screen;
View Model - one view model which will initiate fetching and persistance model objects;
View - in your case, it's a place where you do most of your work. Create custom control based on ItemsControl with Canvas panel. Custom control should pass collection of the model objects in ItemsSource, allow to drag and drop containers and call the view model command when user drops container in some place
Have a look at the Telerik controls, specifically radTileView, this seems to have the functionality that your looking for. They also have a persistance framework that should allow you to save the position of the tiles back to you database.

Linking controls in separate views

I have two separate views each containing a ScrollViewer. I want to slave one to the other in terms of scrolling. (Views are being injected using PRISM)
I can do this trivially if they are in the same view. However I seem to be stuck doing it between isolated views. (The views are isolated for a good reason... well I think!)
What I think I want to do is echo the ScrollViewer 'ScrollChangedEvent' to the ViewModel layer then use some linking service to pass a message to the 2nd ViewModel.
However I'm struggling to work out how to drive the 2nd ScrollViewer from the ViewModel without violating MVVM.
Sure I'm missing something obvious so a shove in the right direction would be greatly appreciated.
Thanks
There are several ways to go about this. One would be, as you suggested, to transfer the scroll change to the view model. From there you can use a loose pub/sub mechanism (such as Prism's Event Aggregator) or a shared object that is available to both view models to transmit the event from one view model to the other.
My recommendation would be to use Prism.
When the second view model receives the event, it can publish it to the view using another event the view can directly consume, or through a property (using an attached property you can bind to that calls ScrollViewer.ScrollToVerticalOffset)

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

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.

WPF, WCF, Entity, MVVM doubts!

I am using a WCF service reference in a WPF project, and my entity framework data model resides in WCF project.
And I am using MVVM Light framework. I am doing the following things:
I use LINQ in the service to get data and then fetch it from WPF, obersvablecollections usually.
Everything works in view part like populating datagrid, views as required.
But I have following doubts:
Is this correct way of transferring data between wcf and wpf.
I haven't used the Model for anything yet, I have doubt about when to use it?
I also wanted to save data from datagrid. I was able to pass on the observablecollection of updated data of datagrid to the service's function. But how do i update the entity from this collection? by looping? doesnt sound right. Once I update the entity from this collection I will be able to use saveChanges to update into database.
When I need to show hierarchal data in a treeview, where to make that data hierarichal, from stored procedure xml? use a view to create a grouping criteria column? create this column in service? create this column/property in presentation?
1 - There is no correct way, it depends on your requirements and goals.
2 - With MVVM, the model should sit between WPF and the database. That means all calls to the database should go through the model, and all writes to the database should also go through the model. The WPF GUI should only bind to the model. This usually means that your WPF portion consists mostly of XAML code. All code that accesses the database should be in the model.
There are good reasons for separating this.
You can write unit tests that on the model.
The view model is independent from the look of the GUI. This means that you can easily change the GUI by dropping in different components and just binding to the model.
A quick google search can probably yield more reasons.
3 - I would try to send over only the entities that have changed. This can be done by passing the collection to your view model, and have your view model figure out what has changed.
4 - I don't quite understand what you want to do. Usually, to make a TreeView, you should create HierarchicalDataTemplate for each of your view models. The TreeView control will take care of the rest. You should really do some tutorials on this one, because it's kinda hard to wrap your head around.

Resources