【问题标题】:Xamarin.Forms buttons become disabled after touchedXamarin.Forms 按钮在触摸后变为禁用
【发布时间】:2019-05-29 19:18:59
【问题描述】:

我使用 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; 
})

【问题讨论】:

  • 你的命令代码是什么样的?
  • 只是为了扩展 Gerald 的评论,您在 OptionSelectedCommand 中的代码是什么?
  • 这是我的 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

标签: button mvvm xamarin.forms command mvvmcross


【解决方案1】:

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

我认为 MvvmCross MvxAsyncCommand 有一个关于运行异步方法的错误

【讨论】:

  • 不确定您的答案为何被否决。我有同样的问题。按钮变为禁用,并非总是如此,但大多数时候在执行后。感谢您的提示,从 MvxAsyncCommand 更改为 MvxCommand 也为我修复了它。
  • 不幸的是,即使在 MvvmCross 6.4.0 中,问题仍然存在,这很尴尬。
  • 解决方法只是消除了这个问题,但是,命令变得不异步,并且它不会锁定可以再次按下的按钮。
  • 6.4.1 仍然存在问题。
【解决方案2】:

Mehmet 是正确的,这个问题的根源在于 MvxAsyncCommand。我发现我的 MvxAsyncCommand 的 CanExecute() 方法总是返回 false。当 CanExecute() 返回 false 时,Xamarin Forms 按钮将被禁用,这是预期的行为。但是为什么 CanExecute() 总是返回 false 呢?我深入研究了源代码,发现如果 MvxAsyncCommand 的 CanExecute() 方法认为任务正在运行,它将返回 false。如果您在 MvxAsyncCommand 的构造函数中将 allowConcurrentExecutions 设置为 true,它将绕过该检查并且按钮将再次启用。

这需要在 MvxAsyncCommand 中修复,但设置 allowConcurrentExecution = true 是一种临时解决方法。

MvxAsyncCommand on Github:

public bool CanExecute(object parameter)
{
    if (!_allowConcurrentExecutions && IsRunning)
        return false;
    else
        return CanExecuteImpl(parameter);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多