2010-08-24 4 views
2

J'ai une liste de méthodes que je souhaite appeler et un bouton accompagnant chacune d'entre elles ainsi qu'une méthode générique pour gérer les boutons. En utilisant CommandArgument, comment puis-je exécuter la méthode sélectionnée?Appel d'une méthode en C# déterminée par un paramètre

E.g. Cliquez sur le bouton exécuter la méthode1. Dans handler pour le bouton click, appelez la méthode comme indiqué dans commandArgument

+0

Vous devriez vraiment penser à changer votre programme-modèle pour utiliser des délégués pour les méthodes - ceci est possible d'abuser, en particulier lorsqu'il est utilisé avec des chaînes comme arguments .. –

+0

argh ... définir un tag pour asp.net et révoqué mon répondre. –

Répondre

1

Si vous devez le faire, vous pouvez utiliser la réflexion. Je suppose que vous avez essentiellement obtenu un événement de clic sur un bouton pour chaque bouton ou que vous ne poseriez pas ceci:

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); 
} 

Bien que cela ressemble à une odeur de code massif. Pourquoi devez-vous le faire de cette façon? Pourquoi ne pouvez-vous pas donner à chaque bouton un gestionnaire d'événements distinct et appeler chaque méthode directement?

Sinon, pourquoi ne pas utiliser une instruction switch sur l'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; 
    } 
} 
+0

Ahh ... c'est lent et dangereux ... mieux serait d'utiliser des délégués à la place. –

1

Si vous connaissez toutes les méthodes à appeler et le nombre n'est pas très grand, j'utiliserais simplement une instruction switch pour les appeler. Sinon, vous devez utiliser la réflexion, voir par ex. http://www.codeproject.com/KB/cs/CallMethodNameInString.aspx pour quelques exemples. Par conséquent, la chaîne dans le CommandArgument correspond au nom d'une méthode?

+0

Je sais mais je voulais permettre à la liste de croître. Je l'ai juste temporairement mis en place en utilisant une déclaration de cas de commutation – DazManCat

3

Pourquoi ne pas utiliser en fait quelque chose comme ce modèle de commande?

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); 
} 
+1

Vous pouvez aussi bien utiliser l'événement Button.Command plutôt que l'événement Button.Click. Vous obtiendrez un paramètre CommandEventArgs qui contient à la fois CommandName et CommandArgument, de sorte que vous n'aurez pas besoin de les extraire du bouton lui-même. (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.command.aspx) –

+0

Vous avez raison d'utiliser l'événement de commande, je tapais ceci rapidement et j'ai modifié le bouton -cliquer le code d'appel d'une réponse précédente –

1

J'aime la réponse de Ian, mais si vous voulez quelque chose de moins complexe, vous pouvez simplement mettre en place un dictionnaire de délégués:

private IDictionary<string, Action> actions = new Dictionary<string, Action> { 
    { "MethodA", MethodA }, 
    { "MethodB", MethodB } 
}; 

puis

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); 
} 

bien sûr, pourrait être modifié pour accepter les arguments si vous connaissez leur type. cela suppose que MethodA et MethodB n'ont pas d'arguments et retournent void.

Questions connexes