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

标签 wpf mvvm command prism

我有一个简单的窗口,其中有一个按钮与带有命令的 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>

和我的 View 模型:
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()调用回调到 CanDoStuff异步使用 Dispatcher.CurrentDispatcher.BeginInvoke ,避免您在 Prism 的实现中看到的行为。

关于wpf - 当命令 CanExecute 为 false 时,按钮不会被禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15032689/

相关文章:

c# - 如何在WPF中绘制网格

wpf - 命名空间中不存在名称 ViewModelLocator

wpf - 资源字典定位器

MVVM 有什么用? window 电话 8

c# - 检查窗口是否真正关闭的更好方法

wpf mvvm threading.Timer 和 TimerCallback 问题

shell - 如何从另一个文件的文件中删除特定内容?

symfony - 检查 prod env 中的学说设置

c# - 命令绑定(bind)不起作用 - MVVM Light RelayCommand 和 XAML 问题

wpf - F# 异步显示 WPF 窗口