代码之家  ›  专栏  ›  技术社区  ›  CareTaker22

在Action<object>list中使用多个动作

  •  4
  • CareTaker22  · 技术社区  · 7 年前

    我正在学习更多关于使用 ICommand 接口以及如何通过 RelayCommand I类创建。

    首先,我做了一些关于我想要达到的目标的研究,但我找不到任何帮助,或者我真的不知道如何寻找我想要做的事情。另外,我对C#理论的了解不是很好,所以这对我也不有利。

    基本上,我尝试将多个动作发送到我的 继电器命令 然后遍历 List<Action<object>> 收集并逐一执行。这是我的代码:

    RelayCommand类构造函数

    public RelayCommand(Predicate<object> canExecute, List<Action<object>> actions)
    {
        _canExecute = canExecute;
    
        foreach (var action in actions)
            _execute = action;
    }
    

    然后在我的 视图模型

    private ICommand _updateExternals;
    public ICommand UpdateExternals
    {
        get
        {
            if (_updateExternals == null)
            {
                _updateExternals = new RelayCommand(
                    x => CanExecute,
                    Updater.UpdateExternals(this));//Here is where I am stuck
            }
            return _updateExternals;
        }
    }
    

    从其他例子中我知道,如果我只需要通过一个 Action 而不是代码如下所示的操作列表: x => Updater.UpdateExternals(this)); 这是可行的,但只要我有一个动作列表作为参数,我就会被卡住。

    所以,如果您还没有猜到,我的问题是:如何将多个动作发送到我的RelayCommand类?

    任何正确方向的帮助都将不胜感激,谢谢!

    编辑: 这是我的完整RelayCommand课程,让我对自己正在做的事情有更多的了解。

    public class RelayCommand : ICommand
    {
        private Predicate<object> _canExecute;
        private Action<object> _execute;
    
        public RelayCommand(Predicate<object> canExecute, List<Action<object>> actions)
        {
            _canExecute = canExecute;
            foreach (var action in actions)
                _execute = action;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public bool CanExecute(object parameter)
        {
            return _canExecute(parameter);
        }
    
        public void Execute(object parameter)
        {
            _execute(parameter);
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  6
  •   Evk    7 年前

    要解决您的问题,请使用 params 在构造函数中:

    public class RelayCommand : ICommand {
        private Predicate<object> _canExecute;
        private Action<object>[] _execute;
    
        public RelayCommand(Predicate<object> canExecute, params Action<object>[] actions) {
            _canExecute = canExecute;
            _execute = actions;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public bool CanExecute(object parameter) {
            return _canExecute(parameter);
        }
    
        public void Execute(object parameter) {
            foreach (var action in _execute)
                action(parameter);
        }
    }
    

    然后您可以像往常一样创建这样的命令:

    _updateExternals = new RelayCommand(
        x => CanExecute,
        x => Updater.UpdateExternals(this));//Here is where I am stuck
    

    当您需要传递多个操作时:

    _updateExternals = new RelayCommand(
        x => CanExecute,
        x => Updater.UpdateExternals(this),
        x => Updater.DoSomethingElse(this));
    
        2
  •  2
  •   Sindri Jóelsson    7 年前

    然后在执行方法(接口实现)中,您只需迭代操作并逐个调用它们。

    public class RelayCommand : ICommand
    {
        private Predicate<object> _canExecute;
        private List<Action<object>> _executes;
    
        public RelayCommand(Predicate<object> canExecute, List<Action<object>> actions)
        {
            _canExecute = canExecute;
            _executes = actions;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public bool CanExecute(object parameter)
        {
            return _canExecute(parameter);
        }
    
        public void Execute(object parameter)
        {
            foreach(e in _executes )
            {            
               e(parameter);
            }
        }
    }
    

    您最初的代码所做的是使用构造函数参数中的每个动作一遍又一遍地分配单个动作引用,这样您的类只会在以下情况下执行列表中的最后一个动作: Execute 被称为。

    记住一个 Action Action<T>