Hackmodford
Hackmodford

Reputation: 3970

How to use ReactiveUI with MvvmCross

I would like to use parts of ReactiveUI in an MvvmCross application. I am not using Xamarin.Forms.

I have managed to create a ViewModel based on ReactiveObject. While it does seem to work, I'm worried there might be ramifications in MvvmCross that I do not understand.

public abstract class ReactiveMvxViewModel : ReactiveObject, IMvxViewModel
    {
        protected ReactiveMvxViewModel()
        {

        }
        
        public virtual void ViewCreated()
        {
        }

        public virtual void ViewAppearing()
        {
        }

        public virtual void ViewAppeared()
        {
        }

        public virtual void ViewDisappearing()
        {
        }

        public virtual void ViewDisappeared()
        {
        }

        public virtual void ViewDestroy(bool viewFinishing = true)
        {
        }

        public void Init(IMvxBundle parameters)
        {
            InitFromBundle(parameters);
        }

        public void ReloadState(IMvxBundle state)
        {
            ReloadFromBundle(state);
        }

        public virtual void Start()
        {
        }

        public void SaveState(IMvxBundle state)
        {
            SaveStateToBundle(state);
        }

        protected virtual void InitFromBundle(IMvxBundle parameters)
        {
        }

        protected virtual void ReloadFromBundle(IMvxBundle state)
        {
        }

        protected virtual void SaveStateToBundle(IMvxBundle bundle)
        {
        }

        public virtual void Prepare()
        {
        }

        public virtual Task Initialize()
        {
            return Task.FromResult(true);
        }

        private MvxNotifyTask _initializeTask;
        public MvxNotifyTask InitializeTask
        {
            get => _initializeTask;
            set => this.RaiseAndSetIfChanged(ref _initializeTask, value);
        }

        public ViewModelActivator Activator { get; }
    }
    
    public abstract class ReactiveMvxViewModel<TParameter> : ReactiveMvxViewModel, IMvxViewModel<TParameter>
        where TParameter : notnull
    {
        public abstract void Prepare(TParameter parameter);
    }

    //TODO: Not possible to name MvxViewModel, name is MvxViewModelResult for now
    public abstract class ReactiveMvxViewModelResult<TResult> : ReactiveMvxViewModel, IMvxViewModelResult<TResult>
        where TResult : notnull
    {
        public TaskCompletionSource<object> CloseCompletionSource { get; set; }

        public override void ViewDestroy(bool viewFinishing = true)
        {
            if (viewFinishing && CloseCompletionSource != null && !CloseCompletionSource.Task.IsCompleted && !CloseCompletionSource.Task.IsFaulted)
                CloseCompletionSource?.TrySetCanceled();

            base.ViewDestroy(viewFinishing);
        }
    }

    public abstract class ReactiveMvxViewModel<TParameter, TResult> : ReactiveMvxViewModelResult<TResult>, IMvxViewModel<TParameter, TResult>
        where TParameter : notnull
        where TResult : notnull
    {
        public abstract void Prepare(TParameter parameter);
    }

This seems to work. I am able to use a MvxViewController and bind to the properties using MvvmCross's method of binding.

But since the viewmodel is no longer a MvxViewModel I can't use SetProperty. Which is probably fine, but are there any other problems I would run into with the approach down the line?

I like MvvmCross and how it handles navigation, dependency injection, etc.

Upvotes: 0

Views: 172

Answers (1)

Artyom
Artyom

Reputation: 516

Worth checking out the Interoperability with ReactiveUI article by Rodney Littles II. This article is so so good at explaining how ReactiveUI works and how to combine ReactiveUI with other MVVM frameworks. There is also a ReactiveUI.Interop repository that contains code examples, including interoperability examples with FreshMvvm, Prism, and MvvmCross. See also ReactiveUI.Interop/src. There is a SetProperty<T> method available (see MvxReactiveViewModel.cs).

Upvotes: 1

Related Questions