MvvmCross IMvxNavigationFacade,MvxViewModelRequest 导致调用 Init() 而不是 Prepare()

MvvmCross IMvxNavigationFacade, MvxViewModelRequest causes Init() to be called rather than Prepare()

我在我的 MvvmCross 5.6.x 示例应用程序中实现了用于深度链接的 IMvxNavigationFacade。我在 BuildViewModelRequest() 中添加了逻辑来构造一个 MvxViewModelRequest,其参数作为 MvxBundle 传入。

if (url.StartsWith("http://www.rseg.net/rewards/"))
{
    var parametersBundle = new MvxBundle();
    var id = url.Substring(url.LastIndexOf('/') + 1);
    parametersBundle.Data.Add("id", id);
    return Task.FromResult(
        new MvxViewModelRequest(typeof(RewardDetailViewModel),
        parametersBundle, null));
}

但是,这种方法会导致在目标 ViewModel 中调用旧式 Init() 方法,而不是新类型安全的 Prepare() 方法。

public class RewardDetailViewModel :
    MvxViewModel<RewardDetailViewModel.Parameteres>
{
    ...

    public new void Init(string id)
    {
        if (!string.IsNullOrWhiteSpace(id))
        {
            if (int.TryParse(id, out _rewardId))
                RaiseAllPropertiesChanged();
        }
    }

    public override void Prepare(Parameteres parameter)
    {
        if (parameter != null)
        {
            _rewardId = parameter.RewardId;
            RaiseAllPropertiesChanged();
        }
    }
}

有没有一种方法可以构建 MvxViewModelRequest,以便为目标 V​​iewModel 传入参数 class 的实例,从而导致调用 Prepare() 方法?

整个解决方案可以在GitHubhttps://github.com/rsegtx/So.MvvmNav2

上查看

提前致谢!

经过一些研究后,我至少找到了一种方法来完成此任务。 创建一个 ViewModelInstanceRequest 而不是 ViewModelRequest,这样你就可以调用 ViewModelLoader.LoadViewModel 传入一个参数对象; ViewModelRequest 只允许使用 MvxBundle 传递参数。对 NavigationFacade 上的 BuildViewModelRequest() 进行以下更改:

var request = new
    MvxViewModelInstanceRequest(typeof(RewardDetailViewModel));
var parameters = new RewardDetailViewModel.Parameteres();

.... parse parameters and fill in parameters object

request.ViewModelInstance = ViewModelLoader.LoadViewModel(
    request, parameters, null);

return Task.FromResult((MvxViewModelRequest)request);

创建您自己的 IMvxNavigationService 并添加逻辑以检查从 NavigationFacde 返回的对象,如果它是 ViewModelInstanceRequest,则按原样使用它而不是之前创建的对象。

var facadeRequest = await facade.BuildViewModelRequest(path,
    paramDict).ConfigureAwait(false);

...     

if (facadeRequest is MvxViewModelInstanceRequest)
    request = facadeRequest as MvxViewModelInstanceRequest;
else
{
    facadeRequest.ViewModelType = facadeRequest.ViewModelType;
    if (facadeRequest.ParameterValues != null)
    {
        request.ParameterValues = facadeRequest.ParameterValues;
    }
    request.ViewModelInstance = ViewModelLoader.LoadViewModel(
        request, null);
}

我已经在 GitHub https://github.com/rsegtx/So.MvvmNav2 上更新了原始示例。