当命令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%时间会被禁用,但它从来不会这样做。 该命令不会执行,但我仍然可以单击该按钮。 如何让WPF明白当CanExecute()为false时应该禁用该按钮?


我看到你正在使用Prism和它的NotificationObjectDelegateCommand ,所以我们应该期待RaiseCanExecuteChanged()中没有错误。

但是,行为的原因是Prism的RaiseCanExecuteChanged同步运行,因此CanDoStuff()ICommand.Execute()的实现中仍处于调用状态,结果似乎被忽略。

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

或者,如果你用MVVM Light和RelayCommand尝试同样的事情,你的代码就可以工作,因为MVVM Light的RaiseCanExecuteChanged调用CommandManager.InvalidateRequerySuggested() ,它使用Dispatcher.CurrentDispatcher.BeginInvoke异步调用CanDoStuff回调,避免了Prism的行为实现。


你可以试试这个( Microsoft.Practices.Prism.dll是必须的)

public class ViewModel
{
    public DelegateCommand ExportCommand { get; }

    public ViewModel()
    {
        ExportCommand = new DelegateCommand(Export, CanDoExptor);
    }

    private void Export()
    {
        //logic
    }

    private bool _isCanDoExportChecked;

    public bool IsCanDoExportChecked
    {
        get { return _isCanDoExportChecked; }
        set
        {
            if (_isCanDoExportChecked == value) return;

            _isCanDoExportChecked = value;
            ExportCommand.RaiseCanExecuteChanged();
        }
    }

    private bool CanDoExptor()
    {
        return IsCanDoExportChecked;
    }
}
链接地址: http://www.djcxy.com/p/56131.html

上一篇: Button doesn't become disabled when command CanExecute is false

下一篇: How can I refresh the UI in MVVM WPF