启用/禁用按钮的RelayCommand不能像预期的那样工作

时间:2018-01-16 10:48:18

标签: c# wpf .net-4.6.2

案例是我尝试在点击窗口时禁用窗口中的按钮,经过一段时间(几秒钟)后,它应该再次启用。

但是这没用。单击该按钮后,该命令将启用设置为false,几秒钟后命令将其设置回true(我测试了它,顺序正确并将其设置为{{1}再次)但窗口表单上的按钮仍未启用。

对于那种情况,我使用trueRelayCommmand是您在Internet上找到的标准类,最后会显示。 为了组织命令,我写了一个名为RelayCommand的类:

Testclass

在XAML文件中,我添加了一个按钮:

class Testclass
{
    private bool _testValueCanExecute;
    public bool TestValueCanExecute
    {
        get { return _testValueCanExecute; }
        set
        {
            _testValueCanExecute = value;
            OnPropertyChanged();
        }
    }

    public ICommand TestValueCommand { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    public Testclass()
    {
        TestValueCommand = new RelayCommand(TestMethod, param => _testValueCanExecute);
        TestValueCanExecute = true;
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private async void TestMethod(object obj)
    {
        TestValueCanExecute = false;
        await Task.Delay(3000);
        TestValueCanExecute = true;
    }
}

<Button x:Name="TestButton" Command="{Binding TestValueCommand}" Content="Test Button" HorizontalAlignment="Left" Margin="149,96,0,0" VerticalAlignment="Top" Width="75"/> 代码如下所示:

MainWindow

因此public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new Testclass(); } } 使用RelayCommand方法将命令启用变量设置为TestMethod,等待3秒并将其设置回false。但是,正如我上面写的那样,窗口表单上的按钮仍未启用。

理解这里发生的事情以及如何解决这个问题会很高兴。

更新的 我对true使用以下代码:

RelayCommand

2 个答案:

答案 0 :(得分:1)

  

In [140]: B.__mro__ Out[140]: (__main__.B, __main__.A, object) 是您在互联网上找到的标准课程。

没有“在互联网上找到的标准课”这样的东西。事实上,互联网上有function incrementSecond(){ amount +=3; timesClicked.innerHTML = amount; if (amount % 10 === 0) { gold++; gold.innerHTML = gold; } } 可用的几种不同的实现方式。

一个好的实现应该包含一个引发RelayCommand事件的方法。 MvvmLight的实现有一个RelayCommand方法来执行此操作。您需要调用此命令来“刷新”命令的状态:

CanExecuteChanged

当您设置RaiseCanExecuteChanged()属性并为视图模型引发private async void TestMethod(object obj) { RelayCommand cmd = TestValueCommand as RelayCommand; TestValueCanExecute = false; cmd.RaiseCanExecuteChanged(); await Task.Delay(3000); TestValueCanExecute = true; cmd.RaiseCanExecuteChanged(); } 事件时,事件会自动引发。

修改:您的实施没有任何TestValueCanExecute方法。在PropertyChanged课程中添加一个并按上述方式调用:

RaiseCanExecuteChanged()

答案 1 :(得分:0)

我强烈建议使用现有的框架,而不是再次投票。 看看ReactiveUI ReactiveCommand

在您的情况下,它会自行完成所有工作:

TestValueCommand = ReactiveCommand.CreateFromTask(async () => await Task.Delay(500));

将该命令绑定到xaml中的按钮,该按钮被禁用,直到命令完成。

您可以轻松添加另一个禁用命令的条件,然后绑定将禁用按钮