在Action <object>列表中使用多个Actions

时间:2017-11-01 08:15:41

标签: c# action icommand

我正在学习使用ICommand接口以及如何通过我创建的RelayCommand类执行命令。

首先,我对我想要实现的目标进行了一些研究,但是我找不到任何可以帮助我的东西,或者我真的不知道如何搜索我想要做的事情。另外,我对C#理论的了解并不是很好,所以也不利于我。

基本上我正在尝试将多个操作发送到我的RelayCommand构造函数,然后遍历List<Action<object>>集合中的所有操作并逐个执行它们。这是我的代码:

RelayCommand类构造函数

public RelayCommand(Predicate<object> canExecute, List<Action<object>> actions)
{
    _canExecute = canExecute;

    foreach (var action in actions)
        _execute = action;
}

然后我的 ViewModel

中的命令属性
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 个答案:

答案 0 :(得分:5)

要解决您的问题,请在构造函数中使用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));

答案 1 :(得分:2)

您的类需要有一个要执行的操作列表,因此将其添加为类中的字段,然后在构造函数中设置它。 然后在您的Execute方法(接口实现)中,您只需迭代操作并一个接一个地调用它们。

$workbook = new COM("EasyXLS.ExcelDocument");
//for xls file
$rows = $workbook->easy_ReadXLSActiveSheet_AsList("file.xls");
//or 
//for xlsx file
$rows = $workbook->easy_ReadXLSXActiveSheet_AsList("file.xlsx");
for ($rowIndex=0; $rowIndex<$rows->size(); $rowIndex++)
{
    $row = $rows->elementAt($rowIndex);
    $employee_name = $row->elementAt(0);
    $employee_designation = $row->elementAt(1);
    $employee_salary = $row->elementAt(2);

    $stmt = $DBcon->prepare("INSERT INTO employee(employee_name,employee_designation,employee_salary) VALUES(:employee_name,:employee_designation,:employee_salary)");

    $stmt->bindparam(':employee_name', $employee_name);
    $stmt->bindparam(':employee_designation', $employee_designation);
    $stmt->bindparam(':employee_salary', $employee_salary);
    $stmt->execute();
}

原始代码正在做的是使用构造函数参数中的每个操作一遍又一遍地分配单个操作引用,这样您的类只会在调用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); } } } 时执行列表中的最后一个操作。 / p>

请记住,ExecuteAction或多或少只是对某个方法的引用,名为或匿名(lambda)。