wpf - 按钮保持禁用状态 - DelegateCommand 未重新评估 CanExecute 处理程序

标签 wpf mvvm binding

问题 :按钮永远不会被启用。

<Button Name="btnCompareAxises"Command="{Binding CompareCommand}"
          Content="{Binding VM.CompareAxisButtonLabel}" 
        IsEnabled="{Binding VM.IsCompareButtonEnabled}">
</Button>

ViewModel 构造函数:
 this.CompareCommand = new DelegateCommand(CompareCommand, ValidateCompareCommand);

问题似乎与按钮的注册命令的 CanExecute 事件处理程序有关。
CanExecute 处理程序在应用程序加载时返回 false。
这很好,因为最初没有满足条件。

canExecute 处理程序仅在应用程序启动或单击按钮时运行。您不能单击禁用的按钮,因此如果从 CanExecute 处理程序返回的初始值为 false,则该按钮将永远保持禁用状态!

问题:
我是否必须再次启用该按钮,仅使用绑定(bind)到它的命令。
像,嘿命令,请重新评估是否满足此按钮的条件?

为什么 IsEnabled 属性位于 Coercion 部分而不是 local 部分?

enter image description here

命令:
public class DelegateCommand : ICommand
{
    private readonly Func<object, bool> canExecute;
    private readonly Action<object> execute;

    public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        this.OnCanExecuteChanged();
    }

    protected virtual void OnCanExecuteChanged()
    {
        var handler = this.CanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

最佳答案

已解决:
我必须调整 DelegateCommand 类以使其工作:

我已添加 CommandManager.RequerySuggested公开CanExecuteChanged事件属性。

现在它会在 UI 中发生某些变化时自动重新评估命令的 CanExecute 方法!

public class DelegateCommand : ICommand
{
    private readonly Func<object, bool> canExecute;
    private readonly Action<object> execute;

    public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    /// CommandManager
    /// Go to the "References" part of your class library and select "Add Reference". 
    /// Look for an assembly called "PresentationCore" and add it.
    public event EventHandler CanExecuteChanged
    {
        add
        {
            _internalCanExecuteChanged += value;
          CommandManager.RequerySuggested += value;

        }
        remove
        {
            _internalCanExecuteChanged -= value;
            CommandManager.RequerySuggested -= value;
        }
    }

    event EventHandler _internalCanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        this.OnCanExecuteChanged();
    }

    protected virtual void OnCanExecuteChanged()
    {
        var handler = this._internalCanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

从按钮中删除了这个:
 IsEnabled="{Binding VM.IsCompareButtonEnabled}"

这里的绑定(bind)不是必需的,因为 CanExecute 处理程序将处理按钮的启用/禁用状态!

关于wpf - 按钮保持禁用状态 - DelegateCommand 未重新评估 CanExecute 处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38931438/

相关文章:

wpf - 绑定(bind)到 ViewModel.SubClass.Property(子属性)

c# - 在 C# WPF 中为 MVVM 数据绑定(bind)定义属性的简洁方法

c# - 在 C# 和 WPF 中,可以将数组的元素绑定(bind)到对象属性吗?

mysql - 我应该如何将 DataTable 转换为分配给 DataGrid.ItemsSource?

c# - 如何将通用项添加到绑定(bind)到 WPF 中的集合的 ComboBox

wpf - wpf mvvm datagrid选定的行

javascript - 在 ES6 中替代 .on ('error' , this.onError.bind(this)) ?

c# - 如何将组合框绑定(bind)到 WPF 中的多语言值集合?

wpf - 使用触发器进行复选框检查

c# - 无法在 Telerik 中使用附加 Y 轴的绑定(bind)