Hey,
Ich programmiere mir gerade ein TicTacToe (ich weiß, schon 1000x gesehen) mit Winforms. Die 9 Spielfelder stelle ich mit Buttons dar. Jetzt habe ich eine Frage zu den Buttons:
Jeder Button braucht nur eine Methode aufrufen, die sich um den Rest kümmert. Es wäre also ziemlich unübersichtlich/unperformant für jeden Button einen eigenen EvenHandler alà
private void button_1_1_Click(object sender, EventArgs e)
{
Spiel.SpielzugHinzufuegen(1, 1);
}
zu erstellen.
Können die Buttons irgendwie zusammengefasst werden, z.B. zu einem Array? Und wie übergebe ich dann die zum Button passenden Positionen 1/1, 1/2, usw?
Ich danke euch =)
Hallo Skillord,
die 9 Buttons platzierst du am besten per Designer.
Bezüglich Events schlage ich vor du abonnierst bei jedem Button das selbe Click Event. Im Click Event castest du den sender nach Button und schon hast du den aufrufenden Button und kannst mit dem machen was du willst.
Es wäre also ziemlich unübersichtlich/unperformant für jeden Button einen eigenen EvenHandler
Unperformant ist es nicht, aber unnötig, da jedes Event "fast" das selbe machen soll.
Gruß
Michael
Und im Button.Tag - Property kannst du dir die Array-Position speichern (z.B. als 0-8) und dann mittels
Button button = sender as Button;
int row = (int)(button.Tag) / 3;
int col = (int)(button.Tag) % 3;
wieder in Reihe und Spalte zurückrechnen.
P.S: Ich würde die Buttons trotzdem dynamisch im Code erzeugen...
Edit: Sorry @xxMUROxx, hast recht - muß entsprechend gecastet werden (habe den Code angepaßt).
(bei der VCL ist die Eigenschaft 'Tag' einfach ein int -)
Button button = sender as Button; int row = (int)(button.Tag) / 3; int col = (int)(button.Tag) % 3;
besser sowas
new Point(row,col);
😉
Hallo TheGear,
noch ne Anmerkungen für etwaige zukünftige Probleme mit cast
oder as
Parameter.
Bei as
wird wenn das casten fehlschägt null
zurückgegeben, desswegen empfiehlt sich eine abprüfung nach null
.
Bei (int)
wird ein Fehler geworfen falls sich darauf folgende object nicht casten lässt.
Jedoch ist in deinem Beispiel das abprüfen nach null
nicht nötig, da der Sender immer ein Button sein wird. War nur ne Anmerkung.
Gruß
Michael
int row = button.Tag / 3;
Sei jedoch angemerkt dass Tag vom Typ object ist. Allerdings sei auch noch angemerkt, dass der Designer die Eingabe für die Tag-Property immer als String speichert, auch wenn man einen numerischen Wert eingibt. (So jedenfalls meine bisherigen Erfahrungen.)
P.S: Ich würde die Buttons trotzdem dynamisch im Code erzeugen... Wenn man die Buttons ohnehin schon programmatisch erstellt, kann in das Tag-Property direkt ein Point-Objekt gespeichert werden. Dann spart man sich im Click-Eventhandler den kleinen Trick mit "/ 3" und "% 3". Was, wie ich finde, ohnehin umständlicher und auf den ersten Blick unverständlicher Code wäre.
Wenn im Tag direkt ein Point steckt, kommt man mit
Point point = (Point)button.Tag;
an das Objekt und kann entsprechend die X- und Y-Properties auswerten.
Gruß,
Andreas
Hallo xxMUROxx,
noch ne Anmerkungen für etwaige zukünftige Probleme mit cast oder as Parameter...
das ist mir durchaus klar ich habe lediglich zitiert.
Hallo aadler,
Wenn man die Buttons ohnehin schon programmatisch erstellt, kann in das Tag-Property direkt ein Point-Objekt gespeichert werden
das habe ich mit meinem obigen Post gemeint 😃
Wollte es nicht zu deutlich machen weil es eigentlich alles zu den Basics gehört.
André