5

The action :

readonly Action _execute;

public RelayCommand(Action execute)
             : this(execute, null)
{
}

public RelayCommand(Action execute, Func<Boolean> canExecute)
{
    if (execute == null)
        throw new ArgumentNullException("execute");
    _execute = execute;
    _canExecute = canExecute;
}

Other class's code:

public void CreateCommand()
{
    RelayCommand command = new RelayCommand((param)=> RemoveReferenceExcecute(param));}
}

private void RemoveReferenceExcecute(object param)
{
    ReferenceViewModel referenceViewModel = (ReferenceViewModel) param;
    ReferenceCollection.Remove(referenceViewModel);
}

Why do I get the following exception, how can I fix it?

Delegate 'System.Action' does not take 1 arguments

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
idish
  • 3,190
  • 12
  • 53
  • 85
  • 1
    the code you have prsented **does not show** the line at which the error occurs. If you are using any IDE, please double-click on the error line, and the IDE will jump right to the offending line. If you are not using IDE, read the FULL log of errors, and the "file:number" will be presented somewhere. Without looking at the exact place, it's much harder to tell what's wrong. Having said that, and judging by the error message, I'm guessing that @JOHN has hit the point. Please attach relevant code next time! [here, it'd be the place where you try to execute the 'execute' delegate] – quetzalcoatl Dec 25 '12 at 10:05
  • 2
    @quetzalcoatl Are you sure the error does not come from `RelayCommand command = new RelayCommand((param)=> RemoveReferenceExcecute(param));}`, which is in the question? Agreed with the sentiment, this should have been pointed out. –  Dec 25 '12 at 10:25
  • In the first class, `RelayCommand`, you have `_execute` as an `Action`. That's a delegate type that has 0 parameters and returns `void`. We can't see how `_execute` is used. But it is probably something like `_execute();` (note: 0 arguments). In the "other class", your method `CreateCommand` seems to create a `RelayCommand` but (unless there's more inside the `CreateCommand` body) it looks like it is not used or kept. The problem, as already pointed out, is that there is 1 argument on the left-hand side of your lambda arrow `=>`, but the delegate you use needs 0 arguments. – Jeppe Stig Nielsen Dec 25 '12 at 11:26
  • If you changed (for example) `Action` to `Action`, then the signature of your `RemoveReferenceExcecute` would match, and this simple syntax would be allowed: `command = new RelayCommand(RemoveReferenceExcecute);` (by "method group" conversion). – Jeppe Stig Nielsen Dec 25 '12 at 11:28
  • @hvd: you are right, I've not noticed this one. If RelayCommand has only this one constructor, then surely this is the issue - `(param)` would not match the parameterless `Action` – quetzalcoatl Dec 25 '12 at 22:00

3 Answers3

11

System.Action is a delegate for parameterless function. Use System.Action<T>.

To fix this, replace your RelayAction class with something like the following

class RelayAction<T> {
    readonly Action<T> _execute;
    public RelayCommand(Action<T> execute, Func<Boolean> canExecute){
        //your code here
    }
    // the rest of the class definition
}

Note RelayAction class should become generic. Another way is to directly specify the type of parameter _execute will receive, but this way you'll be restricted in usage of your RelayAction class. So, there are some tradeoff between flexibility and robustness.

Some MSDN links:

  1. System.Action
  2. System.Action<T>
InteXX
  • 6,135
  • 6
  • 43
  • 80
J0HN
  • 26,063
  • 5
  • 54
  • 85
  • If it's a class to implement [`ICommand`](http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx), the class should probably not be generic, and the delegate type should be `Action`, because `object` is what its [`Execute`](http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.execute.aspx) method is passed. –  Dec 25 '12 at 10:28
3

You can define your command 'RemoveReferenceExcecute' without any parameters

RelayCommand command = new RelayCommand(RemoveReferenceExcecute);}

or you can pass some parameters / objects into it:

RelayCommand<object> command = new RelayCommand<object>((param)=> RemoveReferenceExcecute(param));}

In the second case do not forget to pass CommandParameter from your view;

Trinitron
  • 374
  • 3
  • 12
0

In my case, this is what happened.

This is the method that required an empty action

    public LTDescr setOnStart( Action onStart ){
        this._optional.onStart = onStart;
        return this;
    }

here is the way to call it

    .setOnStart(()=>{ 
            
    })
Lasitha Lakmal
  • 486
  • 4
  • 17