wpf – 当命令CanExecute为false时,按钮不会被禁用

我有一个简单的窗口,带有一个带有命令的ViewModel按钮.

我希望如果MyCommand.CanExecute()为false,则禁用该按钮.但似乎WPF只会在首次绘制窗口时设置IsEnabled属性.任何后续操作都不会影响按钮的可见状态.我正在使用Prism的DelegateCommand.

我的观点:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Button Content="Click Here" Command="{Binding MyCommand}" Width="100" Height="50"/>
</Grid>

和我的ViewModel:

public class MyVM : NotificationObject
{
    public MyVM()
    {
        _myCommand = new DelegateCommand(DoStuff, CanDoStuff);
    }

    private void DoStuff()
    {
        Console.WriteLine("Command Executed");
        _myCommand.RaiseCanExecuteChanged();
    }

    private bool CanDoStuff()
    {
        var result =  DateTime.Now.Second % 2 == 0;
        Console.WriteLine("CanExecute is {0}", result);
        return result;
    }

    private DelegateCommand _myCommand;

    public ICommand MyCommand
    {
        get
        {
            return _myCommand;
        }
    }
}

50%的时间,当我的应用程序加载时,按钮被正确禁用.但是,如果在窗口加载时启用它,并且我单击按钮执行命令,我希望该按钮有50%的时间被禁用,但它永远不会.该命令不会执行,但我仍然可以单击该按钮.当CanExecute()为false时,如何让WPF理解应该禁用该按钮?

最佳答案
我看到你正在使用Prism及其NotificationObject和DelegateCommand,所以我们应该期望RaiseCanExecuteChanged()中没有错误.

但是,行为的原因是Prism的RaiseCanExecuteChanged同步操作,所以当我们仍在ICommand.Execute()的实现中时调用CanDoStuff(),然后结果似乎被忽略.

如果您使用自己的命令创建另一个按钮并从该命令/按钮调用_myCommand.RaiseCanExecuteChanged(),则会按预期启用/禁用第一个按钮.

或者,如果你尝试同样的事情MVVM光与RelayCommand您的代码将工作,因为MVVM光的RaiseCanExecuteChanged调用CommandManager.InvalidateRequerySuggested()调用它使用异步的Dispatcher.CurrentDispatcher.BeginInvoke回调CanDoStuff,避免你与棱镜的看到的行为实现.

转载注明原文:wpf – 当命令CanExecute为false时,按钮不会被禁用 - 代码日志