C# Buttons in Schleife generieren: btn[x,y].Click wie zuweisen ?

Michael_P

Cadet 2nd Year
Registriert
Mai 2011
Beiträge
17
Hallo Programmierfreunde,

Ich bin gerade an einem Projekt drann das folgendes machen soll (auch wenns nonsense klingt):

Ein Fenster mit Textbox (Eingabe: Zahl von 1 - 15) und einen Button (übergibt Zahl in Textbox an 2. Fenster). Das 2. Fenster soll nun einen Raster aus Buttons generieren mit der Größe (x-, y- Achse) der im 1. Fenster eingegebenen Zahl.

Dazu habe ich eine for Schleife verwendet und ein 2-dimensionales Array arr [x, y].

die Buttons werden wie folgt erstellt und platziert (x und y werden immer erhöht):

Code:
arr[x, y] = new Button();
arr[x, y].Name = "btn"+x+""+y+"";
//arr[x, y].Click += new EventHandler([arr[x, y]_Click);  
arr[x, y].Size = new Size(46, 46);
arr[x, y].Text = ""+xb+"/"+yb+"";
arr[x, y].Left = x * 45;
arr[x, y].Top = y * 45;
panel1.Controls.Add(arr[x, y]);

So, das was ich hier auskommentiert habe ist mein Problem.
Wie kann ich jeden einzelnen Button das Click-Event für sich selbst übergeben ?
Ich habe es auch über den Namen dem der Button eine Zeile zuvor gegeben wird, aber ohne Erfolg da die Namen nicht vor der Laufzeit vorhanden sind und so mir Visual C# das Programm nicht kompilieren will ...


Hat jemand eine Idee ?


Vielen Dank schon mal im Voraus :D
 
Ein Event-Handler in C# hat immer die Form
Code:
void Control_Click( object sender, EventArgs e )
sender wird automatisch gefüllt durch das Control das du klickst. Du musst also nur eine einzige Funktion übergeben und in dieser kannst du Fallunterscheidungen machen.
Code:
arr[x, y].Click += new EventHandler( ButtonGrid_Click );

void ButtonGrid_Click( object sender, EventArgs e )
{
  if( sender.Equals( arr[0,0] ) ) Aktion_fuer_Button_0_0();
  else if( sender.Equals( arr[0,1] ) ) Aktion_fuer_Button_0_1();
  // ...
  // evtl. ließe sich das auch mit einem switch() abfangen,
  // bin mir da aber gerade nicht sicher, ob das auch für Controls/Objekte funktioniert
}
 
Vielen Dank für die Antwort, es funktioniert !

Nur habich jz ein weiteres Problem:

der Button, der geklickt wird, soll eine andere Backgroundfarbe haben was ich bereits erledigt habe, nun sollen aber die umliegenden Buttons (sind dann 8 (oben, oben links+rechts, unten, unten links+rechts, rechts und links vom Button)) auch eine andere Farbe haben.

Mit welcher Eigenschaft der Buttons soll ich hier arbeiten ? Mit der Indexnummer im Panel ? mit der Indexnummer der Buttons ? Mit dem Namen oder den Koordinaten ?

Ich habe es schon probiert aber mit dem rückrechnen auf die Indexnummern (von Buttons oder Panel) gibt es Probleme.

Ist zwar kompliziert zu erklären aber ich hoffe ihr wisst was ich meine xD
 
Hallo Michael_P,

als erstes würde ich dein Code so umformulieren:
Code:
Button b = new Button();
b.Name = "btn"+x+""+y+"";
b.Click += (sender,args) =>
{
    //Hier kannst du jetzt inline das definieren was pro button passieren soll
   // zum beispiel abhängig von x und y
}  
b.Size = new Size(46, 46);
b.Text = ""+xb+"/"+yb+"";
b.Left = x * 45;
b.Top = y * 45;
// wenn du das unbedingt nochmal in dem array speichern musst dann halt so
arr[x,y] = b;
panel1.Controls.Add(arr[x, y]);
 
Um es euch einfacher zu machen hab ich hier mal seperat das gemacht, was per Button-Klick geschehen soll wenn der hier blaue Button geklickt wird: [siehe Anhang]
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    140,5 KB · Aufrufe: 386
Sieh dir mal die Eigenschaft Tag an, dort kannst du beliebige Sachen hinterlegen. An deiner Stelle würde ich hierbei die x/y-Koordinaten abspeichern, damit du im Nachhinein noch Zugriff auf das Grid hast.
Mal aufbauend auf dem Code von toeffi:
Code:
b.Tag = new System.Collections.Generic.KeyValuePair<int, int>( x, y );
Somit hast du erstmal die Koordinaten separat hinterlegt und kannst damit mehr oder weniger unabhängig arbeiten.
Code:
void ButtonGrid_Click( object sender, EventArgs e )
{
  Button Sender = sender as Button;
  KeyValuePair<int, int> xy = (KeyValuePair<int, int>)Sender.Tag;
  int x = xy.Key, y = xy.Value;
  
  Sender.BackColor = Color.Teal;
  
  Color altColor = Color.Red;
  // xLength = maximale x-Koordinate + 1 - äquivalent zu .Length, .Count, ...
  // yLength = maximale y-Koordinate + 1 - äquivalent zu .Length, .Count, ...
  if( x - 1 > 0 && y - 1 > 0 ) arr[x - 1, y - 1].BackColor = altColor; // oben links [x - 1, y - 1]
  if( y - 1 > 0 ) arr[x, y - 1].BackColor = altColor; // oben [x, y - 1]
  if( x + 1 < xLength && y + 1 < yLength ) arr[x + 1, y + 1].BackColor = altColor // oben rechts [x + 1, y + 1]
  // ...
}
 
Hey cool B)

Vielen dank, ich werd mich gleich nach den Mittagessen dahinterklemmen xD

Mahlzeit :D
Ergänzung ()

So mein Programm sieht nun so aus:
Code:
Button Sender = (Button) sender;
KeyValuePair<int, int> xy = (KeyValuePair<int, int>)Sender.Tag;
 int x = xy.Key, y = xy.Value;
  
            Sender.BackColor = Color.Teal;
  
Color altColor = Color.Red;
int xLength = rg+1; //rg = Größe des Rasters (sowohl Zeilen (x) als auch Spalten (y))
int yLength = rg+1;
if (y - 1 > 0) arr[x, y - 1].BackColor = altColor; // oben [x, y - 1]
if (x - 1 > 0 && y - 1 > 0) arr[x - 1, y - 1].BackColor = altColor; // oben links [x - 1, y - 1]
if (x + 1 < xLength && y - 1 < yLength) arr[x + 1, y - 1].BackColor = altColor; // oben rechts [x + 1, y + 1]
if (y + 1 > 0) arr[x, y + 1].BackColor = altColor; // unten [x, y + 1]
if (x - 1 < xLength && y + 1 < yLength) arr[x - 1, y + 1].BackColor = altColor; // unten links [x - 1, y + 1]
if (x + 1 < xLength && y + 1 < yLength) arr[x + 1, y + 1].BackColor = altColor; // unten rechts [x + 1, y + 1]
if (x - 1 < xLength) arr[x - 1, y].BackColor = altColor; // links [x - 1, y]
if (x + 1 < xLength) arr[x + 1, y].BackColor = altColor; // rechts [x + 1, y]

Wenn ich jedoch an den Rand des Rasters (äußerste Buttons) klicke, kommt der Fehler dass dieser Bereich ausserhalb des Arrays ist !

Ich hab zwar schon viel herumprobiert, das Array erst bei 1 zu füllen beginnen, jedoch ist dann alles um x+1 und y+1 verschoben bei den Farben ...
Ergänzung ()

Perfekt funktioniert wunderbar :D

Vielen dank Yuuri :D
Dein Tipp mit dem Tag war ausschlaggebend :D
 
Zurück
Oben