How to pass data back in when closing a view

2019-08-11 06:59发布

问题:

I have a ViewModel that has a command that opens another view:

public ICommand OpenAnotherViewCommand
{
    get 
    {
        return new MvxCommand(() => ShowViewModel<AnotherViewModel>());
    }
}

So far, so good. Then in AnotherViewModel I want to be able to go back to the first view model. Originally I did something like this:

public ICommand ReturnCommand
{
    get
    {
        Dictionary<string, string> parameters = new Dictionary<string, string>();
        // Add some stuff from this model to pass to the first view model

        return new MvxCommand(() => {
            ShowViewModel<FirstViewModel>(parameters);
        }
     }
 }

I added an InitFromBundle to my first view model and this worked too. However, then I realized that my original first view model still existed (I noticed this because of some event handlers that seemed to be firing multiple times!). My ShowViewModel created an new FirstViewModel, but the old one was never destroyed (it seems really obvious now). So the stack of views is now first -> another -> first when it ought to be just first.

So after face palming over that I replaced my ShowViewModel in ReturnCommand with Close(this) and now I've fixed the navigation problem and I'm not producing a long line of unneeded view models. However, what I've lost is the ability to pass back data from AnotherViewModel to the first one.

So how can I pass data back to my first view model when the second one is closed?

回答1:

1

As you may already know you can always use a form of variable in your view models which is accessible from another view model. For instance using a static variable. However, imo it's not a good practice specially when you are going to repeat this pattern across your application.

2

In your case I think you can benefit from MvvmCross Messenger plugin. Look at N=9 at MvvmCross N+1 for more information on the implementation. A sample source code is also available here.

By using the messenger plugin then it's easy. You simply publish a message before closing down the child view. The parent view has already subscribed to receive that kind of message and the rest should be straight forward.