How to make view model and model communicate? - wpf

I am using MVVM pattern for my app. The model actually runs a set of test in parallel and keeps tab of the status of the test including its result. I want the status and result to be displayed in the view. I am stuck at desiging the view model.
The problem is that there are lots of classes and sub class hierarchy in the model in which all the required data to be displayed in the view are stored. Those data are dynamic.
I am not sure how to design the view model now.
I was thinking along these lines - Create a new data structure in view model which reflects what is to be shown in the view and get all the view model will dig through the model to get the required data. In this case I am confused how the model will update the view model whenever a data changes. Or how do the model and view model communicate with each other given that the data are stored in different class and sub classes.

Your view model should have references of all models which required to show data on the view. Then view model should handle events from model classes and fire NotifyPropertyChanged event.
If your view is complex and require lots of models, then you can consider to split your view in multiple views and corresponding view model.

You say the user chooses which data to view, so I imagine your VM could hold an array of Models and an index indicating which is the 'active' one, and only communicate with that one.
For that communication, a solution could be to pass to the model an Action to call when new data is available, and that Action would that trigger a NotifyPropertyChanged in the VM. This would work especially well if you make sure only the 'active' model has that Action while in the others it would be null meaning 'don't trigger updates'.

Related

Reusing WPF MVVM Views

I've inherited an application which uses the view-first MVVMC patern
In the application I've created 2 step process which creates a person and assigns them to a group. To do this I've created a view and corresponding view model (all views have a 1-2-1 relationship with a view model, view models are injected into the View constructor and are registered with the Unity container using the TransientLifetimeManager) called CreatePersonMaster, the view simply contains a region (shown by the dashed line) which sub-views can be loaded into and the view model subscribes to two loosely coupled events, "PersonCreated" and "GroupSelected". The "PersonCreated" event saves a Person entity in a field and the "GroupSelected" event takes the saved Person, creates a Group association and saves them to a database.
This view/view model doesn't do anything until the events get raised so I load the following sub views into my the region.
These views/view models fire the events which get handled by the master view.
I also have an edit view where I want to re-use the select group view.
I can do this by subscribing to the appropriate events in the EditPersonMaster view model.
My question really is, is this the appropriate way to do this? Because I'm using loosely coupled events I don't get any feedback into the sub-View/ViewModels if there's an error when creating/reassigning? I could probably fire another "ErrorBlah" event for the inner view/model to handle and update the view.
Is there another way to do this? Composite commands don't seem to fit the bill but maybe I don't understand them correctly.
Here is how I understood your question: You have persons stored in a database, which have a property/column group. In your UI, you want to create persons and assign the group property. Also, you want to be able to edit the group property of existing persons in a different region/page/master. You want to reuse the control for assigning the group. Your controls fire an event, which is handled by the Master in a way that it creates the entries in the database (is that correct?). Your question is whether this is a good approach and what alternatives you have?
I see two options:
1. Modularize your business logic:
You could inject a data service into your ViewModels, which could access the database directly. This way you can handle errors etc.. directly where they occur and don't have to pass them through the whole system. If you want to notify other modules of changes on the database (specifying the changed dataset or so), you can do so with a composite event. I think of the PRISM modules more as of complete elements, including UI and business logic and keep communication between them as little as possible.
2. Keep your business logic central and share it:
If you want to stick to your architecture, have singleton Model which is injected into the ViewModels. Manage your state in the model and have the ViewModels pick the pieces they want to provide to their view.
Hope I got he point, though...

Should views keep track of their model?

This nice article recommends against keeping track of the views belonging to a model inside the model. What about the opposite? It is recommended for views to keep track of the model(s) they are based on?
It seems difficult to imagine to do without. Maybe the recommended way is to use events, or something?
Views always keep a reference to the model. It is accessible through myView.model or myView.collection.models.
Due to the nature of views, I cannot imagine a case where you would want the view to not know about the model. Event binding happens in the view with a reference to a model. (Think about the collection.add event. Wouldn't be possible if you didn't bind to a reference to the collection)
Most of the time the view should know its model cause he is the visualization of the model. So the model can be there without a view, but a view without a model doesn't make much sense.
But as always there are cases where the view should not know its model directly. Think about a basket where a user can add products and maybe he can configure that products. You have different views that visualize the model, like a table with the products, a basket ico with the count of products and a view to show the total amount. All share the same model. So when ever the user creates a new model cause he delete the old one or order something and there after something new, you have to create a new model and pass it to your views. Sure you can to this by fire an event. But you can also pass a proxy for your model to your views, so the views always comunicate with your proxy and they never know that sometimes a new model was created.

MVVM where does the code to load the data belong?

As I wrap my head around the mvvm thing, the view is the view, and the viewmodel is 'a modal of a view' and the model are the entities we are dealing with (or at least that is my understanding). But I'm unclear as to what and when the model entities are populated. So for example:
Lets say I have app that needs to create a new record in a DB. And that record should have default values to start with. Who is responsible for the new record, and getting the default values. Does this have anything to do with MVVM or is that part of a data access layer? Who calls the the viewmodel?
Or for existing records when\where are the records retrieved? And saved if altered?
Thanks
In an overly simplified answer, your ViewModel should contain the LOGIC for controlling what your View displays, as well as how it is allowed to interact with the Model or Data.
Events like Getting data, Saving and Deleting are intercepted through a Command mechanism and pushed into the ViewModel, where they can be tested. Handling 'Dirty' events are also the duty of the ViewModel. As for who Calls the ViewModel, you are entrusting the Calling to the Binding mechanisms available within WPF and Silverlight.
Within the ViewModel it is still about staying with best practices and ensuring that you have a DataAccess layer abstracting your Data Source and possibly using the Repository pattern to abstract that.
The life cycle of a ViewModel could be as simple as the following...
Constructor called by View
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
However since you will probably have a lot of moving parts within the Ctor of the VM, including the Data Repositories Interface you will probably want to work with an IoC. This will make the life cycle of the ViewModel closer to...
View/ViewModel (Depends if you are View or ViewModel first) is pulled out of the IoC
IoC Handles the pairing of the View-ViewModel (Convention based)
Data Repository is Injected into the ViewModel
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
This may seem like more steps, however with an IoC container you are really just calling a single method like IoC.Get(), and the rest of the steps are wired up automatically based on the conventions applied.
I use view-models to control loading (with defaults) and saving my models, and to create collections and objects that I use to bind to my views. This includes setting default values on my models.
State and Bahavior of your view is define in your viewmodel which means all events are declared here.
Who calls the the viewmodel?
it depends who needs it. you can call it in your view.
for existing records when\where are the records retrieved? And saved if altered?
saving and retrieving part is in your viewmodel.
For detailed explanation, visit this site.

WPF/SL EventAggregator implementation with durable subscribers behavior?

Currently I'm building an application using latest Prism for Silverlight 4.
I've a module and in that module I've two views with view models. Also I've a module view with two regions for each view.
In module initialization I'm registering my views and view models in Unity container and also register views with corresponding regions.
The problem is that views should display something similar to table-detail information - first view shows available entities ans the second view shows detail of selected entity.
I need a way how to pass them initial selected entity. Newly created first view doesn't have any selected entity and newly created second view doesn't show any details.
Currently I'm doing that this way:
In module I create two view models and register them as instances in Unity container and then I register views as types for corresponding regions. Each view subscribes to EntitySelectedEvent from EventAggregator. Module initializer publish this event after initialization and this way two views are selecting the same entity.
I know this looks ugly - I tried publishing this event from one of view models but the problems is that EventAggregator in Prism doesn't support durable subscribers - this means that if the second view model didn't subscribe to event before the first view model fired it, it won't receive and event. I know this is a normal behavior of EventAggregator, but I'm looking for a solution when view models can fire events without depending on initialization order of them - that is the first model can fire event before the second model was created and the second model will receive this 'queued' event after subscribing to it.
Are there any other messaging implementations for WPF/SL which do support such behavior or using a mediator (in my example it's a module itself) isn't such a bad idea after all? One big problem with mediator is that models must be created right away in initialize and they can't be registered as types in container because this leads again to missing subscribers.
Create a Model that will be shared by ViewModels of each of the views.
When a row gets selected in View 1 its ViewModel (via a CurrentEntity property bound to a selected row) will update the Model.
ViewModel of View 2 would subscribe to changes of Model's CurrentEntity and will properly update it's own CurrentEntity property that would cause it's View to update.

MVVM WPF ViewModels for Adding New Entity

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.

Resources