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.