C# - Dynamisch Buttons erstellen - Event Problem



  • Hallo,

    ich erstelle mehrere Panels mit einer TextBox und einem Button wärend der Laufzeit.
    Dabei kann ich auf die Button mit bnt[i] und auf die TextBoxen mit txt[i] zugreifen.
    Nun habe ich jedem Button das Click Event btn_click hinzugefügt.
    Das Problem ist jetzt, woher weiß ich welcher Button gedrückt wurde.
    Ich möchte je nach geklicktem Button, die jeweilige Textbox auslesen.

    Ich denke, dass das irgendwie mit dem sender oder e Parameter geht, aber es ist das erste Mal, dass ich mit Events arbeite und
    verstehe noch nicht wie die funktionieren.

    [...]
    btn[i] = new Button();
    btn[i].Click += btn_click;
    txt[i] = new TextBox();
    pnl[i] = new Panel();
    pnl[i].Controls.Add(btn[anzBtn]);
    pnl[i].Controls.Add(txt[anzBtn])
    [...]
    Form1.Controls.AddRange(pnl);
    [...]
    void btn_click(object sender, EventArgs e)
    {
        // ToDo: Auswertung            
    }
    

    Ich hoffe jemand kann mir helfen,
    Viele Grüße,
    Samuirai 😉


  • Administrator

    sender verweist auf das Objekt, von welchem das Event kommt, in deinem Fall also den Button. Also grundsätzlich könntest du nun sowas machen:

    // Falls du den Index willst:
    void btn_click(object sender, EventArgs e)
    {
      for(int i = 0; i < buttonCount; ++i)
      {
        if(btn[i] == sender)
        {
          // Ok, es war der i-te Button.
        }
      }
    }
    
    // Falls du nur den Button willst:
    void btn_click(object sender, EventArgs e)
    {
      Button button = (Button)sender;
    
      // ...
    }
    
    // Falls du den Index willst und klug bist:
    btn[i] = new Button();
    btn[i].Tag = i;
    // ...
    
    void btn_click(object sender, EventArgs e)
    {
      Button button = (Button)sender;
      int index = (int)button.Tag;
    }
    

    Oder du könntest Objekte erstellen, welche die Funktionalität ausführen, also ca:

    public class ActionObject
    {
      // ... die benötigten Daten ...
      public void doAction(object sender, EventArgs e)
      {
        // Arbeite mit den Daten.
      }
    }
    
    // ...
    btn[i] = new Button();
    ActionObject actionObject = new ActionObject(/* ... */);
    btn[i].Click += actionObject.doAction;
    

    Mehr fällt mir so spontan und um die Uhrzeit nicht ein 🙂

    Grüssli



  • Dravere schrieb:

    // Falls du nur den Button willst:
    void btn_click(object sender, EventArgs e)
    {
      Button button = (Button)sender;
    }
    

    Gefährlich, weil sollte das Objekt kein Button sein kommt ne InvalidCastException zur Laufzeit. Besser so:

    // Falls du nur den Button willst:
    void btn_click(object sender, EventArgs e)
    {
      Button button = sender as Button;
      if( button == null ) // sender ist kein button, also abbruch.
      {
          return;
      }
    }
    

  • Administrator

    loks schrieb:

    Gefährlich, weil sollte das Objekt kein Button sein kommt ne InvalidCastException zur Laufzeit.

    Die Frage ist, wann sollte es kein Button sein? Und wenn es kein Button ist, wäre es dann nicht besser, eine Exception wird geworfen, wenn der EventHandler btn _click heisst?

    Grüssli



  • btn[i] = new Button();
    txt[i] = new TextBox(); 
    btn[i].Click += (sender,o) =>
                  { 
                      //mache was mit txt[i] z.B. text ausgeben
                      MessageBox.Show(txt[i].Text);
                  }
    

    So hast du jedem Button seinen Handler zugewiesen und kannst dort jeweils was mit der Textbox machen.



  • Du kannst ganz einfach "command" eigenschaft von button ausnutzen ( muss natürlich bei der erstellung erst zuweisen )
    http://msdn.microsoft.com/de-de/library/system.web.ui.webcontrols.button.command.aspx


Anmelden zum Antworten