Xamarin MVVM双击执行两次命令,IsBusy不工作
所以我有一个按钮,它绑定到一个登录命令Xamarin MVVM双击执行两次命令,IsBusy不工作,xamarin,mvvm,xamarin.forms,Xamarin,Mvvm,Xamarin.forms,所以我有一个按钮,它绑定到一个登录命令 private ICommand loginCommand; public ICommand LoginCommand { get { if (loginCommand == null) { loginCommand = new Command(login, CanExecuteCommand);
private ICommand loginCommand;
public ICommand LoginCommand
{
get
{
if (loginCommand == null)
{
loginCommand = new Command(login, CanExecuteCommand);
}
return loginCommand;
}
}
CanExecuteCommand
操作返回!IsBusy
在login()操作中,我以IsBusy=true
开始,以IsBusy=false结束代码>
在IsBusy
的setter中,我还调用ChangeCanExecute()
方法,如下所示:
((命令)comm.ChangeCanExecute()代码>
当我调试ChangeCanExecute
时,它实际上是在方法的开始和结束时对命令实例调用的。但是,如果我双击该按钮,它仍会调用该命令两次。为什么呢?使用MVVM禁用双击的最干净方法是什么。。。顺便说一下,在另一个VM上,我使用相同的方法,它工作得非常好,但是在执行的命令中,我调用了一个异步方法,所以我使用了await
。也许这就是它在那里工作的原因?在login
案例中,我在命令中调用了void
方法,因此如果我双击按钮,调用就会排队?我仍然不明白为什么ChangeCanExecute+IsBusy
还不够
附言。
当我的命令在VM中定义时,IsBusy、CanExecuteCommand
和ChangeCanExecute
事件的引发发生在BaseViewModel
中
编辑1:
在login()
中,我有如下代码:
{IsBusy=true;DoSomething();IsBusy=false;}
这有我解释过的意外功能,它会被调用两次。但是,如果我将其更改为在任务中,就像在工作VM中一样,双击是不可能的,有什么线索吗?
IsBusy=true;
Task.Run(()=>
{
DoSomething();
}).safefireandfolve();
IsBusy=false;
我查看了关于这一点的答案,他们似乎没有使用MVVM方法,他们提供了使用TapGestureRecognizer
/其他一些似乎不是最佳MVVM实践的解决方案。在我看来,您描述的是基于您使用的代码的正常行为。我认为该命令是否会被调用两次取决于两次单击事件之间的持续时间
例如,假设您的DoSomething()代码>需要2秒(仅为示例)才能完成。然后,如果两次单击事件之间的持续时间小于2秒,则该命令将只执行一次,这正是您想要的。如果持续时间超过2秒,将调用该命令两次
即使将方法设为异步并等待它,也是一样的
如果要在一段时间内防止双击,只需添加wait Task.Delay(1000)代码>在DoSomething()之后
以防止在一秒钟内双击。我添加了一个编辑,并举例说明了如何进行编辑。然而,我不认为这是最好的方法,因为我真的不想处理异步内容的复杂性和添加不必要的使用,即使这是通过使用nugetAsyncWaitBestPractices
中的SafeFireAndForget
扩展来完成的,是否可能在第二次单击按钮时,DoSomething();任务已完成,IsBusy是否已更改为false?然后这个命令将被调用两次。是的,我认为这就是发生的事情,这就是为什么如果我使它异步,它们可能一起运行,并且它实际上可以工作……那么……如果是这样,结论是什么?我必须强制所有方法都是异步的,这样就不会在Xamarin中发生双击事件了?或者有什么是有意义的?我应该保持状态吗?不确定这是否更好…如LoginDone=true,只有在失败时才将其更改为false,以便在LoginDone=true时无法执行第二次。。。。我不喜欢这样的想法。这似乎确实解决了问题…这样我就不必做DoSomething()
async任务或将其放入Task.Run()
中,我仍然必须用async
人为地修饰命令的操作
,以便执行等待任务。Delay()
其中我不喜欢,因为async
增加了一点性能和内存开销。但这可能还是比考虑更复杂的问题解决方案要好。目前无法判断,我只知道async/await
如果不是强制性的,那么应该避免,因为编译器会为每个async
用法创建一个类。“您描述的是基于您使用的代码的正常行为。”-因此,结束本讨论,你认为有另一种更聪明的方法来解决这个问题吗?我应该考虑一下,这句话让我重新思考了。不,我认为这是防止在一段时间内双击的正确方法。此外,使用async/await
不会影响应用程序的性能。