当命令CanExecute是假的按钮不被禁用(Button doesn't become d

2019-07-20 09:38发布

我有一个与绑与命令一个ViewModel一个按钮简单-AS-可以是窗口。

我预计,如果MyCommand.CanExecute()是假的按钮被禁用。 但似乎WPF将只设置IsEnabled属性时,首先绘制窗口。 任何后续动作不会影响按钮的可见状态。 我使用从棱镜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>

和我的视图模型:

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()是假的按钮应该被禁用?

Answer 1:

我看你使用棱镜和NotificationObjectDelegateCommand ,所以我们应该期望有没有在RaiseCanExecuteChanged一个bug()。

然而,对于该问题的原因是棱镜的RaiseCanExecuteChanged同步运行,所以CanDoStuff()同时我们还在里面执行所谓ICommand.Execute()结果随后出现被忽略。

如果你有自己的命令创建另一个按钮,并调用_myCommand.RaiseCanExecuteChanged()从命令/按钮,第一个按钮将被激活,你期望/禁用。

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



Answer 2:

你可以试试这个( 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;
    }
}


文章来源: Button doesn't become disabled when command CanExecute is false