开发者

MVVM pattern in wpf - one data model , multiple view models

开发者 https://www.devze.com 2023-01-10 23:55 出处:网络
I am currently designing simple editor as part of learning process. Its basicaly hierarchical tree structure of polygons-lines-points, that is implemented in data model. I need to display these data i

I am currently designing simple editor as part of learning process. Its basicaly hierarchical tree structure of polygons-lines-points, that is implemented in data model. I need to display these data in two views

First view: hierarchical data in tree view item Second view: rendered geometry on screen

Following the MVVM pattern i have implemented model view classes around data model ( point model view, line model view, etc.. ) . In tree view I am using hierarchical data templates to properly display specific data. On second view I need to render current state of geometry, currently its just one model-view wrapper around polygon data class, that travels all children and render them in onRender method. In this case I am using multiple view models over the same data, both for quite different purpose.

There is a problem when I make some modification in tree view model (adding points for example) , resulting in change of underlying data model. However second view model does not directly observe data in model view, it updates render view only if I make开发者_如何学C modification trough its modelview clas. Is there some elegant solution to update both view models concurently ?


I solved this by introducing a Presenter. Here's basically how it works:

  1. My domain model contains some representation of a process (call it a task, workflow, or whatever). It contains the "business logic" for the actual actions you're doing.
  2. My presenter is told to display the process.
  3. It instantiates the ViewModel (and, if necessary, multiple ViewModels) giving each ViewModel a reference to the presenter (a callback).
  4. After instantiating and displaying the ViewModels, it passes them a reference to the Model and tells them to update their state from it.
  5. ViewModels don't maintain a direct reference to the Model. When they want to take an action, they use the callback to the Presenter that was provided to them when instantiated. The Presenter actually executes the action against the Model (process, task, whatever).
  6. After executing the action, the Presenter again passes a reference to the newly updated Model to all of the ViewModels, instructing them to refresh their state.

That keeps them all in sync without any ViewModel having to know about any other ViewModels. All of my Hierarchical ViewModels implement an interface IViewModelWithChildren, which exposes an IEnumerable<IViewModel> property, which lets the Presenter walk any given ViewModel tree and notify all of them, as long as it has a reference to the root ViewModel.

I also like it because it funnels all user actions through a single point (the Presenter callback) and I can inject certain concerns there. For instance, if an unhandled exception happens in the Model logic, I can catch it at that point and instantiate a nice MessageViewModel to display to the user.


If you must use different viewmodels for the two views, you can have the viewmodel for the geometry view subscribe to PropertyChanged on the hierarchical viewmodel, or you can expose a different event for this. That way, the geometry view model will know to look again at the underlying model and update itself.

If you want it further decoupled, you can use an event aggregator, as available in the Prism project.

0

精彩评论

暂无评论...
验证码 换一张
取 消