My model consists of a single main object that the user can add various other objects too. The added objects are stored in List<object> contained within the main object and it’s associated child objects.
So if the project is a house. The user can add a number of Room objects to the house which are stored in List<Room> RoomList. Then each Room can have a number of Furnishings added again stored in each Room List<Furnishing> FurnishingsList
The question is how to implement this in the MVVM approach? When the user adds a new object do i add it to the ObservableCollection in the ViewModel so the view is updated and at the same time add it to the model which is hooked into the VM? Or do i store it in the VM until a save or commit commmand and then pass it to the Model?
In my example i have various editors (each is a user control). So the user can edit the house at a high level, using one editor to add, edit and remove rooms from the house. And, at a lower level, using a different editor to edit each room, adding and removing Furnishings.
So when the user ‘Edits’ a room say. I produce an EditRoomModelView containing said Room. The user adds, edits and otherwise manipulates the furnishings in that room.
At each command is it best to sync the data in the Model and the ModelViee as above. Or do i shove the changes straight into the Model and have the ViewModel provide only getters on the injected Model properties. This way however adding objects to the Model Lists does not update the view. i would really have to add the data to both the ModelView and the Model at the same time so everything is at the same state.
Appologies for rambling, struggling to find a nice approach to this, anyone uderstand what i’m getting at?
I’m not sure there’s a single, good answer. It sounds as though you’re debating as to how to maintain coherence – do you have a simple pass-through scheme from the presentation layer, or do you interpose on user requests and have logic in there.
If that is, in fact, the question, there are various factors at play. Do you prefer to do validation in the presentation layer? How complex is the application and how scaleable does it need to be? Do your view models need to be accessed in multiple places?
So, with all that in mind, I can tell you how I personally prefer approaching this problem (specifically, the issue of adding that you mention). I typically like to create view models that describe user concerns with generics such as
EditItemViewModel<T>orListViewModel<T>. So, in the GUI, there would be some kind of listbox of rooms bound to aListViewModel<Room>. This VM would obviously expose an observable collection, but also commands for Add, Delete, Edit.So, from my perspective, the presentation layer, view-modelly stuff that this VM is going to do is route requests for other GUI concerns. If you click “Add” to add a room, this VM is responsible for initiating a request, via a command, for whatever screen/window/whatever is necessary for room adding, which will have its own VM. This VM, upon receiving an add request, will pass the generated data transfer object down to the domain where validation will occur and whatever domain operations are necessary. I usually handle this via a service layer. Now, if the domain operation was successful, the service layer will raise some kind of even or callback to let the list VM know that there is a change. When that happens, the list VM re-queries its service and updates its observable collection accordingly. Now, your GUI is consistent with the domain across the board.
The reason I favor this type of layered approach is that all of the business logic occurs in a place ‘below’ the GUI, and the GUI need not concern itself with this occurrence. Conceptually, GUI just says “here, domain layer, user wants to add this – do all that, and let any interested GUI components know when you’re done so that they can refresh themselves”.
What I’m describing here will naturally incur some overhead as compared to a simple, pass-through scheme or a scheme in which the VMs just re-expose properties on some model object. But, personally, I think the advantage gained from a decoupling perspective is worth it, especially as you scale up the application. It gives you the ability to fundamentally alter the domain model’s internal interactions without changing the presentation layer code a lick.