I have a WPF/Entity Framework (4.0) project with many objects. I'd like to build the application so that that I can have object selection state shared across viewmodels.
For Example: We have Cars, Drivers, Passengers, and Cargo classes. We also have UserControls for CarList, DriverList, etc. and editor windows for CarEditor, DriverEditor, etc. Furthermore, we have viewmodels for all of these (CarListViewModel, DriverListViewModel, CargoEditorViewModel, etc). This all composes a dockable interface where the user can have multiple object lists, editors, and viewers open.
What I want is a concrete code example of how to wireup multiple viewmodels so that selecting a car in the CarList will cause that car to go live in the CarEditorView, but also be selected in any other view for which the context is valid (such as a DriverByCarView- or just DriverList if there is a filter predicate).
There are a number of suggestions and discussions based on this question. The two methods that seem to dominate are:
Is one of these approaches better than the other?
Does anyone have a concrete example of either/both of these methods in the form of a write-up or small code project?
I'm still learning WPF, so pointers to entry points for reading API fundamentals are appreciated, but looking at code examples is where I usually go.
Thanks
In case anyone is interested, here are some other similar discussions:
One way to have disconnected ViewModels communicate to each other is to use a publish / subscribe mechanism such as PRISMs EventAggregator. However, in a parent / child ViewModel relationship, I think it's fine for the parent to have direct knowledge and control over the child ViewModel.
ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property. It should not contain any method. In the above example, we have the required View model with two properties.
The purpose of ViewModel is to encapsulate the data for a UI controller to let the data survive configuration changes. For information about how to load, persist, and manage data across configuration changes, see Saving UI States.
MVVM (Model-View-ViewModel) MVVM is a way of creating client applications that leverages core features of the WPF platform, allows for simple unit testing of application functionality, and helps developers and designers work together with less technical difficulties.
A typical way to achieve this is to use a messenger to publish a CarSelected message that details the selected car. Zero or more ViewModels can subscribe to the CarSelected message. ViewModels that are interested in the currently selected car can listen for the message and then act accordingly.
The messenger approach provides a clean decoupled design where publishers and subscribers have no dependencies on each other so can easily evolve independently - they just need to know about the car message. Messengers are an implementation of the mediator pattern.
In Prism the messenger is the EventAggregator
and is used for publishing and subscribing to messages.
Update
Apart from the architectural advantages the EventAggregator
brings, it also implements weak events to prevent memory leak issues with subscribers that do not explicitly unsubscribe.
Please see the following for EventAggregator documentation:
http://msdn.microsoft.com/en-us/library/ff649187.aspx
Prism:
http://compositewpf.codeplex.com/
Prism Example
public class ViewModel1 { private readonly IEventAggregator _eventService; private Car _selectedCar; public ViewModel1(IEventAggregator eventService) { _eventService = eventService; } //Databound property... public Car SelectedCar { set { _selectedCar = value; var msg = new CarSelectedMessage { Car = _selectedCar }; _eventService.GetEvent<CarSelectedEvent>().Publish(msg); } } } public class ViewModel2 { public ViewModel2(IEventAggregator eventService) { eventService.GetEvent<CarSelectedEvent>().Subscribe(msg => { //DoStuff with msg... }); } } public class Car {} public class CarMessage { public Car Car { get; set; } } public class CarSelectedEvent : CompositePresentationEvent<CarMessage> {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With