首页 > 解决方案 > Xamarin.Forms & MvvmCross:导航和命令不起作用

问题描述

我创建了 4 个项目:

...带有一些 NuGet 包:Xamarin.Forms 4.4.0.X, MvvmCross.Forms 6.4.2, Xamarin.Essentials 1.4.0, Xamarin.Android.Support.XXX 28.X.X, ...

我在BaseViewModel构造函数中注入了一些服务:IMvxNavigationServiceMyApp.Core.Services.IMyCustomService。他们工作:IMyCustomServiceMyApp.Core.App.Initialize()方法中注册。

在我的HomeViewModel中,我有一个MyText属性(绑定到一个Entry: <Entry Text="{Binding MyText}"/>)和一个命令(绑定到一个ToolbarItem: <ToolbarItem Text="Ok" Command="{Binding OkCommand}"/>):

private string _myText;
public string MyText
{
    get => _myText;
    set => SetProperty(ref _myText, value);
}

public IMvxCommand OkCommand => new MvxAsyncCommand(ExecuteOkCommandAsync, CanExecuteOkCommand);
private async Task ExecuteOkCommandAsync()
{
    await MyCustomService.SomeAsyncWork(); // it works
    await NavigationService.Navigate<MissionsViewModel>();
}
private bool CanExecuteOkCommand() => !string.IsNullOrWhiteSpace(MyText);

2 意外行为

命令仍然不可用

当我在我的条目中键入某些内容并绑定到MyText属性时,该命令仍然不可用。我不知道为什么。_myText是真的设定。

当我通知我的属性已更改时,我尝试使用SetProperty(ref T storage, T value, Action afterAction, string propertyName)并调用:OkCommand.RaiseCanExecuteChanged()

public string MyText
{
    get => _myText;
    set => SetProperty(ref _myText, value, () => OkCommand.RaiseCanExecuteChanged(), nameof(MyText));
}

我的命令仍然不可用。目前,它处于待机状态,我已替换CanExecuteOkCommand() => true.

无法从HomeViewModel.Initialize()方法导航(✔ 已解决)

现在,如果某些情况属实(文件存在),我想从 HomeViewModel 导航到 SecondViewModel。我不需要参数。

ExecuteOkCommandAsync方法中,我调用await NavigationService.Navigate(typeof(SecondViewModel));. 当我从这里导航(调用命令)时,没关系。

但是,当我尝试从HomeViewModel.Initialize()方法导航时,我会看到HomeViewModel工具栏中带有 *back* 按钮的视图:

public override async Task Initialize()
{
    IsBusy = true;

    if (true) // a real condition : if file exists, today is monday, ...
    {
        var result = await NavigationService.Navigate<SecondViewModel>();
    }

    var items = await MyCustomService.GetItemsAsync();
    Items = new ObservableCollection<Item>(items);

    IsBusy = false;
}

当我逐步调试时:

  1. HomeViewModel.Initialize()叫做。var result = await NavigationService.Navigate<SecondViewModel>();也。
  2. SecondViewModel.Initialize()叫做。
  3. 前一个result变量 (in HomeViewModel.Initialize()) 是true
  4. 应用程序显示HomePageSecondPage与预期不同)。

在此处输入图像描述

当我点击工具栏中的“确定”按钮时,我可以导航到真实的SecondPage(显然还有他的SecondViewModel)。

当我按下后退按钮时,从HomePage,我导航到SecondPage...

标签: c#xamarinxamarin.forms

解决方案


我可以覆盖ViewAppeared方法而不是Initialize任务:

public class HomeViewModel 
{
    /* Ommited code  */
    public override async Task Initialize()
    {
        IsBusy = true;
        var items = await MyCustomService.GetItemsAsync();
        // ...
    }

    public override void ViewAppeared()
    {
        base.ViewAppeared();
        if (true)
        {
            NavigationService.Navigate<MissionsViewModel>();
        }
    }
}

推荐阅读