为 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>
我目前正在使用 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>