【问题标题】:Trying to update CanExecute for my commands尝试为我的命令更新 CanExecute
【发布时间】:2019-02-01 15:40:23
【问题描述】:

我创建了一个实现 ICommand 的基本视图模型。命令绑定得很好,按预期执行,甚至以正确的状态开始,但是作为影响命令是否可以执行的属性,这些命令的 CanExecute 似乎没有更新。

在下面的代码中,我可以单击“运行”按钮,一切都按预期工作,除了当 ProgramStatus 更改为“正在运行”时,它应该被禁用。

在我的基本视图模型中:

public class RelayCommand : ICommand
    {

        #region ICommand Member Variables

        private Action<object> _execute;
        private Predicate<object> _canExecute;
        private event EventHandler _canExecuteChangedInternal;

        #endregion // ICommand Member Variables

        #region Constructors

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public RelayCommand(Action<object> execute) : this(execute, DefaultCanExecute)
        {

        }

        #endregion // Constructors

        #region ICommand Members

        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
                _canExecuteChangedInternal += value;
            }

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

        public bool CanExecute(object parameter)
        {
            return _canExecute != null && _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        public void OnCanExecuteChanged()
        {
            EventHandler eventHandler = _canExecuteChangedInternal;

            if (eventHandler != null)
            {
                eventHandler.Invoke(this, EventArgs.Empty);
            }
        }

        private static bool DefaultCanExecute(object parameter)
        {
            return true;
        }

        #endregion // ICommand Members

在我的视图模型中:

RelayCommand _runCommand;
    public RelayCommand RunCommand
    {
        get
        {
            if (_runCommand == null)
            {
                _runCommand = new RelayCommand(param => Run(), param => CanRun);
            }

            return _runCommand;
        }
    }

public bool CanRun
    {
        get
        {
            bool result = false;

            if (Machine.ProgramStatus != ProgramStatus.Running && Machine.ProgramStatus != ProgramStatus.TestRunning)
            {
                result = true;
            }

            return result;
        }
    }

在我看来:

<Button Content="Run" Command="{Binding Path=RunCommand}" />

【问题讨论】:

    标签: wpf binding icommand


    【解决方案1】:

    您必须调用 CanExecuteChanged 事件处理程序。因此,当 ProgramStatus 更改为 Running 时,您可以为要更新的命令调用 OnCanExecuteChanged 辅助方法(例如 RunCommand.OnCanExecuteChanged();)。

    如果 CanExecute 绑定到某个属性,您可以在属性的设置器中使用 OnCanExecuteChanged 辅助方法。

     private bool _myProperty;
     public bool MyProperty
        {
            get { return _myProperty; }
            set
            {
                _myProperty= value;
                RunCommand.OnCanExecuteChanged();
            }
        }
    

    【讨论】:

    • 谢谢。那行得通。我希望 WPF 中的绑定系统有某种魔力可以自动执行此操作,但似乎您仍然需要编写大量代码才能使命令正常运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多