Xamarin.Forms按钮在触摸后变为禁用状态

5

我使用Xamarin.Forms和MvvmCross,但在应用程序中遇到了问题。 有时在触摸并运行命令后,按钮会变为禁用状态。

我向按钮添加了IsEnabled="True",但没有任何变化。

<Button 
    WidthRequest="36" 
    HeightRequest="36" 
    CornerRadius="18" 
    BorderWidth="2" 
    FontSize="18" 
    Text="{Binding OptionText}" 
    Command="{Binding OptionSelectedCommand}" 
    CommandParameter="{Binding .}" 
    IsEnabled="True" 
    VerticalOptions="Center" 
    HorizontalOptions="Center"/>

我希望这个按钮一直保持启用状态。

我的命令代码如下:

new MvxAsyncCommand(async () => 
{ 
    if (option.IsSelected) 
    { 
        option.IsSelected = false; 
    } 
    else 
    { 
        option.OptionGroup.Options.ForEach(c => c.IsSelected = false);
        option.IsSelected = true; 
    } 

    return Task.CompletedTask; 
})

你的 Command 的代码是什么样子的? - Gerald Versluis
只是为了扩展Gerald的评论,你在OptionSelectedCommand中有什么代码? - Tom
这是我的OptionSelectedCommand new MvxAsyncCommand(async () => { if (option.IsSelected) { option.IsSelected = false; } else { option.OptionGroup.Options.ForEach(c=>c.IsSelected=false); option.IsSelected = true;
} return Task.CompletedTask; }); @GeraldVersluis
- Mehmet
可能与此相关:https://github.com/MvvmCross/MvvmCross/issues/1589。 - Tom
2个回答

7

最终我找到了有关这个问题的解决方案。 问题与MvxAsyncCommand相关,通过使用Command而不是MvxAsyncCommand得到了解决。

我认为MvvmCross MvxAsyncCommand在运行异步方法时存在一个bug。


1
不确定为什么你的回答被踩了。我也遇到了同样的问题。在执行后,按钮变为禁用状态,不是每次都会出现,但大多数情况下都会出现。感谢你的提示,改用MvxCommand代替MvxAsyncCommand也解决了我的问题。 - RogerW
不幸的是,即使在MvvmCross 6.4.0版本中,这个问题仍然存在,这相当令人尴尬。 - Agat
解决方法只是消除了问题,但是命令变得不再异步,并且它不会锁定按钮,因此可以再次按下。 - Agat
仍然存在6.4.1的问题。 - masiton

0
Mehmet 正确指出了这个问题的根源在于 MvxAsyncCommand。我发现我的 MvxAsyncCommand 的 CanExecute() 方法总是返回 false。当 CanExecute() 返回 false 时,Xamarin Forms 按钮会变为禁用状态,这是预期的行为。但是为什么 CanExecute() 总是返回 false 呢?我深入研究了源代码,发现如果 MvxAsyncCommand 认为任务正在运行,它的 CanExecute() 方法将返回 false。如果在 MvxAsyncCommand 的构造函数中将 allowConcurrentExecutions 设置为 true,则可以绕过该检查,按钮将再次变为可用状态。
这个问题需要在 MvxAsyncCommand 中解决,但将 allowConcurrentExecution = true 设置为临时解决方法。 Github 上的 MvxAsyncCommand:
public bool CanExecute(object parameter)
{
    if (!_allowConcurrentExecutions && IsRunning)
        return false;
    else
        return CanExecuteImpl(parameter);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接