Quantcast
Channel: patterns & practices: Prism
Viewing all articles
Browse latest Browse all 1878

Commented Issue: An MVVM-friendly way for opening and closing a child window from a view model, and sending data back and forth between the two corresponding view models. [9676]

$
0
0
Feature request:
I have a child window with a view model. The view model has some dependencies that should be injected (I'm using unity). I want to trigger opening this child window from another view model. I want to pass some data to the child window's viewmodel and on closing the child window I want some data back.

It turns out there isn't a ready-to-use solution for this. I prefer to follow the InteractionRequest approach of Prism, and I like the idea of passing context data. I don't like the option of communicating data between the calling view model and the child window's view model using the event aggregator, because in principle any party can subscribe to these events, while the data passing should be private between both view models. Furthermore, the InteractionRequest approach supports a callback mechanism where the context data is returned to the calling view model, with the event aggregator approach this would mean sending yet another event.

Therefore, after quite some experimenting and searching, I ended up with the following approach which I found pretty satisfying:

1) First, to have proper dependency injection in my view models, I obtain an instance of the view model in the constructor of the child window using ServiceLocator.Current.GetInstance. This is perhaps not the nicest way, but it works.

2) Second, I make use of Prism's InteractionRequestTrigger in combination with a custom PopupChildWindow action to open my child window and to pass context data to the view model of the ChildWindow. The child window's view model implements IInteractionRequestDataReceiver. My calling view model calls Raise on an InteractionRequest object and passes an instance of InteractionRequestData as context data. InteractionRequestData is a class that inherits from Notification (this is a requirement of Prism) and forms the data object to pass to the child windows's view model. This is a strongly-typed way of passing data between view models using the InteractionRequest approach. There is no coupling between the view models (apart from the commonly shared InteractionRequestData type, which can be seen as a sort of contract between the two view models). Apart from the parent view, that defines an interaction trigger for, there's no knowledge in the views of the data transfer that takes place.

3) Third, I created an ICloseRequest interface and a CloseRequestor attached property for child windows. My child window's view model implements ICloseRequest, the ChildWindow creates a binding for the CloseRequestor property. The effect is that the view model can raise a Close request, which is then responded to by the child window by closing itself. This is a simple MVVM way for closing a child window from within a view model.

These three things together form a pretty nice MVVM way for firing an interaction request, handling the request in a child window, sending some input data to the child window's view model, closing the child window, and sending back result data to the calling view model. It extends Prism's interaction request pattern by passing the context data not to the child window's data context, but to the view model of the child model (if it implements the IInteractionRequestDataReceiver interface ).

I've attached an example program that makes use of this new meachnism. I hope you like it.

Kind regards,
Merijn
Comments: ** Comment from web user: MdeJ **

Hi Damion,

Thanks for your comments on this issue.

In addition to coupling between two view models, another drawback of using Notification as base class is that this enforces the use of a particular base class and so prevents using another. Since all my view models derive from NotificationObject I would have to break this design to enable using view models in combination with Prism's PopupChildWindowAction.

Your WPF approach looks similar. Perhaps we can merge the two into one to get the best out of two.

Kind regards,
Merijn


Viewing all articles
Browse latest Browse all 1878

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>