I'm learning a bit more about using the ICommand
interface and how to execute commands through the RelayCommand
class I created.
Firstly, I did some research on what I am trying to achieve, but I can't find anything to help me or I do not really know how to search for what I am trying to do. Also, my knowledge of C# theory isn't really good so that's also not in my favour.
Basically I'm trying to send multiple actions through to my RelayCommand
constructor and then iterate through all of the actions in the List<Action<object>>
collection and execute them one by one. Here is my code:
RelayCommand class constructor
public RelayCommand(Predicate<object> canExecute, List<Action<object>> actions)
{
_canExecute = canExecute;
foreach (var action in actions)
_execute = action;
}
And then my command property inside my 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;
}
}
I know, from other examples, that if I only need to pass through a single Action
instead of a list of Actions that the code would look like the following: x => Updater.UpdateExternals(this));
and it would work, but as soon as I have a list of Actions as a parameter I get stuck.
So, if you haven't already guessed, my question is: How can I send through multiple Actions to my RelayCommand class?
Any help in the right direction would be appreciated, thanks!
EDIT: Here is my full RelayCommand class to give more of an idea of what I am doing.
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);
}
}
To solve your problem, use params
in constructor:
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);
}
}
Then you can create such command as usual:
_updateExternals = new RelayCommand(
x => CanExecute,
x => Updater.UpdateExternals(this));//Here is where I am stuck
When you need to pass multiple actions:
_updateExternals = new RelayCommand(
x => CanExecute,
x => Updater.UpdateExternals(this),
x => Updater.DoSomethingElse(this));