为 MvvmCross 5.1.0 创建基础 ViewModel 时遇到问题

Trouble creating a base ViewModel for MvvmCross 5.1.0

我目前正在使用 MvvmCross 框架潜入 Xamarain 的世界。在我当前的项目中,我想使用 MVVM 基础 ViewModel 以便能够在其他 ViewModel 中重用我的一些代码。

在尝试实现此功能时,我 运行 在使用支持在导航之间传递参数的 MvxViewModel 时遇到了问题。

public abstract class BaseViewModel<TParameter> : MvxViewModel, IMvxViewModel<TParameter> where TParameter : class
{
    protected readonly IMvxNavigationService _navigationService;

    public BaseViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public new abstract Task Initialize(TParameter parameter);

}

这样我就可以按如下方式使用 BaseViewModel。

public class ExampleViewModel : BaseViewModel<ExampleParameters>
{
    private ExampleParameters _parameter;

    public ExampleViewModel(IMvxNavigationService navigationService) : base(navigationService)
    {
    }

    public override Task Initialize(ExampleParameters parameter)
    {
        return Task.Run(() => { _parameter = parameter; });
    }
}

在这种情况下,我认为这是一个很好的解决方案。 ExampleViewModel 甚至在我忘记时告诉我需要执行初始化任务。

这个解决方案并不是在所有情况下都很好。当我有不需要传递参数的 ViewModel 时,我仍然需要指定一个参数对象并实现 Initialize 方法。

public class ParameterlessViewModel : BaseViewModel<object>
{
    public ParameterlessViewModel(IMvxNavigationService navigationService) : base(navigationService)
    {
    }

    public override Task Initialize(object parameter)
    {
        return Task.Run(() => { });
    }
}

从 BaseViewModel 中删除抽象方法时,我不需要实现 Initialize 方法,但是当我创建需要传递参数的 ViewModel 时,我不会被迫实现它。

上述解决方案是可行的,但我很好奇是否有人 运行 遇到同样的问题并且可能有更好的解决方案?一种在两种情况下都很好,而无需设置两个 BaseViewModel 类。

亲切的问候,

乔普·米德尔坎普

此文档说明:https://www.mvvmcross.com/documentation/fundamentals/navigation

如果您有 BaseViewModel,您可能无法继承 MvxViewModel<TParameter>MvxViewModel<TParameter, TResult>,因为您已经拥有 BaseViewModel 作为基础 class。在这种情况下,您可以实现以下接口:

IMvxViewModel<TParameter>IMvxViewModelResult<TResult>IMvxViewModel<TParameter, TResult>

如果您使用 TResult,您只需将源代码复制到您的视图模型中即可:

public override TaskCompletionSource<object> CloseCompletionSource { get; set; }

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

我们是否在基础 class 或设备 class 中添加接口 IMvxViewModel,你能举个简单的例子吗

In this case you can implement the following interface:

IMvxViewModel<TParameter>, IMvxViewModelResult<TResult> or IMvxViewModel<TParameter, TResult>