c# - Xamarin.Forms & MvvmCross:导航和命令不起作用
问题描述
我创建了 4 个项目:
MobileApp.Core
,其中包含我的业务代码(.NET Standard 2.0 库)MobileApp.Droid
(适用于安卓 9)MobileApp.iOS
(适用于 iOS 11)MobileApp.UI
,其中包含 Xamarin.Forms 项目 (XAML)
...带有一些 NuGet 包:Xamarin.Forms 4.4.0.X
, MvvmCross.Forms 6.4.2
, Xamarin.Essentials 1.4.0
, Xamarin.Android.Support.XXX 28.X.X
, ...
HomePage
并SecondPage
继承自MvxContentPage<TViewModel>
(在 C# 类和 XAML 文件中)。HomeViewModel
并SecondVieWModel
继承自BaseViewModel
,继承自MvxViewModel
。
我在BaseViewModel
构造函数中注入了一些服务:IMvxNavigationService
,MyApp.Core.Services.IMyCustomService
。他们工作:IMyCustomService
在MyApp.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;
}
当我逐步调试时:
HomeViewModel.Initialize()
叫做。var result = await NavigationService.Navigate<SecondViewModel>();
也。SecondViewModel.Initialize()
叫做。- 前一个
result
变量 (inHomeViewModel.Initialize()
) 是true
。 - 应用程序显示
HomePage
(SecondPage
与预期不同)。
当我点击工具栏中的“确定”按钮时,我可以导航到真实的SecondPage
(显然还有他的SecondViewModel
)。
当我按下后退按钮时,从HomePage
,我导航到SecondPage
...
解决方案
我可以覆盖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>();
}
}
}
推荐阅读
- if-statement - PowerBI 查询不适用于日期过滤器
- visual-studio-code - 在 VS Code 文件资源管理器中抑制二进制文件
- python - 如何在pytest的conftest.py文件中传递命令行选项值
- sql - SQL - 选择列值大于之前行的行
- configuration - 在金字塔视图中使用自定义配置
- mongodb - 如何按数组中与查询匹配的元素数对文档进行排序?
- database - 将 ContactForm Wordpress 连接到另一个 IP 中的另一个数据库
- xslt - 编写 XSL 公式时需要在 for-each 条件中存储先前的元素值
- reactjs - 为什么在使用 useReducer 或 useState 时我的状态没有更新?
- react-native - 如何在 React Native 中监听服务器端事件?