Reputation: 3630
I have a list of methods I wish to call and a button accompaning each and a generic method to handle the buttons.
Using the commandArgument how can I run the selected method.
E.g. Click run method1 button. In handler for button click call the method as named in commandArgument
Upvotes: 2
Views: 593
Reputation: 5437
I like Ian's answer, but if you want something less complex, you could just set up a dictionary of delegates:
private IDictionary<string, Action> actions = new Dictionary<string, Action> {
{ "MethodA", MethodA },
{ "MethodB", MethodB }
};
then
protected void Button_Command( object sender, CommandEventArgs e )
{
if( actions.ContainsKey( e.CommandArgument ) )
actions[e.CommandArgument]();
else
throw new ArgumentException( "Cannot find action for key: "+ e.CommandArgument );
}
of course, could be modified to accept arguments if you know their type. this assumes MethodA and MethodB have no arguments and return void.
Upvotes: 1
Reputation: 2254
Why not actually use something like this command pattern?
public interface ICommand
{
bool CanExecute(string command);
void Execute();
}
public class MethodACommand : ICommand
{
private MyForm form;
public MethodACommand(MyForm form) {... }
public bool CanExecute(string command) { return command.Equals("MethodA"); }
public void Execute() { form.MethodA(); }
}
public class CommandHandler
{
public CommandHandler(IEnumerable<ICommand> commandString) {...}
public Execute(string command)
{
foreach(var command in Commands)
{
if (command.CanExecute(commandString))
{
command.Execute();
break;
}
}
}
}
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
commandHandler.Execute(arg);
}
Upvotes: 3
Reputation: 68506
So the string in the CommandArgument matches the name of a method? If you must do this then you could use reflection. I'm assuming you've basically got a single button click event for each button or you wouldn't be asking this:
private void MethodA() { }
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
MethodInfo method = this.GetType().GetMethod(arg);
method.Invoke(this, null);
}
Although this looks like a massive code smell. Why do you have to do it this way? Why can you not just give each button a separate event handler and call each method directly?
Alternatively, why not use a switch statement on the argument:
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
switch (arg)
{
case "MethodA":
MethodA(); break;
case "MethodB":
MethodB(); break;
}
}
Upvotes: 1
Reputation: 36679
If you know all the methods that are to be called and the number is not very large I would just use a switch statement to call them. Otherwise you have to use reflection, see e.g. http://www.codeproject.com/KB/cs/CallMethodNameInString.aspx for some examples.
Upvotes: 1