Search code examples
mvvmreactiveui

Subscribe to Close, but close only if item was saved


My scenario:

In an MVVM pattern, the view should be closed when a command is executed on ViewModel, but only if the item was successfully saved.

The View looks like:

public class CentreUpdateWindow : ReactiveWindow<CentreUpdateViewModel>
{ 
    public CentreUpdateWindow()
    {
        this.InitializeComponent();
        this.WhenActivated(d =>
           d(ViewModel!.SubmitCommand.Subscribe(CloseIfSuccessfullySaved))
        );
    }

    private void CloseIfSaved(Centre? obj)
    {
        if (ViewModel!.SuccessfullySaved)
            Close(obj);
    }

    // ...

And the ViewModel:

public class CentreUpdateViewModel : ViewModelBase, IId
{
    // ...

    public ReactiveCommand<Unit, dtoo.Centre?> SubmitCommand { get; }

    private bool _SuccessfullySaved;
    public bool SuccessfullySaved
    {
        get { return _SuccessfullySaved; }
        protected set { this.RaiseAndSetIfChanged(ref _SuccessfullySaved, value); }
    }

The question:

The code works fine, but I'm not comfortable with the if (ViewModel!.SuccessfullySaved). I guess should be a way to write subscribe expression more accurate.

Is there a more elegant way to Subscribe on WhenActivated more "reactiveuistic" ?


Solution

  • public CentreUpdateWindow()
    {
        this.InitializeComponent();
        this.WhenActivated(d =>
            d(
                ViewModel
                .WhenAnyValue(x => x.SuccessfullySaved)
                .CombineLatest(ViewModel!.SubmitCommand,
                               (saved, obj) => (saved, obj))
                .Where(s => s.saved)
                .Select(s => s.obj)
                .Subscribe(Close)
            ));
    }