我有一个ViewModel
,它使用Commanding
。在此ViewModel
我想访问MediaPlugin
。使用此插件,我必须致电Initialize()
。因为它使用async
次调用,所以我有一些时间问题。
这是我的代码:
public ICommand CameraCommand
{
get { return _cameraCommand ?? (_cameraCommand = new Command(async () => await ExecuteCameraCommand(), () => CanExecuteCameraCommand())); }
}
public bool CanExecuteCameraCommand()
{
// Check if initialized before calling properties
if (!this.initialized)
InitMedia();
if (!this.initialized || !CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return false;
}
return true;
}
public async Task ExecuteCameraCommand()
{
// Assure that it is initialized before calling method
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions {});
// ...
}
private void InitMedia()
{
CrossMedia.Current.Initialize();
this.initialized = true;
}
使用此代码,应用程序崩溃
在调用任何属性之前,您必须调用Initialize() 在Plugin.Media.MediaImplementation.get_IsCameraAvailable()
当我在构造函数中开始初始化时,就像使用此代码一样
public MyViewModel()
{
InitData();
}
private async Task InitData()
{
// ...
await InitMedia();
}
private async Task InitMedia()
{
await CrossMedia.Current.Initialize();
this.initialized = true;
}
public bool CanExecuteCameraCommand()
{
// Check if initialized before calling properties
if (!this.initialized)
return false;
// ...
}
在初始化完成之前调用 CanExecuteCameraCommand()
。因此,返回false
并禁用UI中的按钮。
我正在Windows 10移动设备(Windows 10 Universal)上的Xamarin.Forms环境中测试此代码。
答案 0 :(得分:2)
您尚未提供Minimal, Complete, and Verifiable code example,特别是您没有展示Command
课程的实施情况。所以我在这里假设它是您引用的Xamarin文章中描述的Command
类。
视图模型的异步初始化的基本策略是:
根据您发布的代码,在我看来,缺少的主要内容是第4步。即你没有做任何事情来重新启用以前禁用的命令,即使你有一个方便的地方:
private async Task InitMedia()
{
await CrossMedia.Current.Initialize();
this.initialized = true;
_cameraCommand.ChangeCanExecute();
}
Command.ChangeCanExecute()
方法引发CanExecuteChanged
事件,以便在CanExecute()
方法的结果不同时,可以通知绑定到命令的控件。通过在初始化完成时调用此方法,这应解决即使在初始化完成后按钮仍保持禁用的问题。
另外需要注意:我会 调用InitMedia()
方法,或者根据CanExecuteCameraCommand()
方法进行任何初始化。因为初始化是异步的,所以不管你是否能够在从该方法返回之前成功初始化,并且你已经从构造函数调用了初始化。 ICommand.CanExecute()
实现应该非常简单,并且严格限于检查事物的当前状态并根据这些结果返回所需的bool
值。
如果上述问题没有解决您的问题,请通过提供良好的MCVE来改进问题,并更详细地解释出现问题的原因,您尝试修复的问题以及具体问题。进行。