In der GUI-Programmierung ist es in einigen Fällen sinnvoller, benötigte Steuerelemente automatisch erstellen zu lassen und diese nicht mit dem Form Designer mühselig zu positionieren.

Als Beispiel habe ich ein Programm geschrieben, das für das Zahlenlotto 6 aus 49 einen Tipp-Schein zeigt. Jedes der 49 Felder wird durch ein Button-Objekt symbolisiert.
Es wäre sicherlich mühsam, alle 49 Button-Objekte mit dem Form Designer zu erstellen und zu positionieren.
Deshalb werden alle Button-Objekte im Form_Load-Event der Form-Klasse erzeugt, mit den notwendigen Eigenschaftswerten versehen (Größe, Position, Beschriftung etc.) und dann dem Controls-Container hinzugefügt.

Das prinzipielle Vorgehen ist:

  • Objekt vom gewünschten Steuerelementtyp erstellen:
    Button b = new Button();
  • grundlegende Eigenschaften des neu erstellten Objekts einstellen; dazu gehören sicherlich Location und Size und vielleicht Text:
    b.Location = new Point(50, 100);
    b.Size = new Size(50,50);
    b.Text = „dynamisch“;
  • dem Controls-Container für alle Steuerelemente hinzufügen:
    Controls.Add(b);

Der Controls-Container, den man in der Designer-Datei findet. enthält alle auf dem Formular darzustellenden Steuerelemente.

Das nachfolgende Bild zeigt das Formular für das (unten beschriebene modifizierte) Lottospiel.

Aussehen des Lottozahlen-Generators zur Laufzeit

Der nachfolgende Programm-Code zeigt die Vorgehensweise:

using System;
using System.Drawing;
using System.Windows.Forms;

using Lottozahlen;

namespace ControlsAutomatischErstellen
{
    public partial class frmMain : Form
    {
        // Array mit Button-Objekten
        Button[] buttons;

        const int buttons_per_row = 7;
        const int buttons_per_column = 7;

        const int distance_left_right = 10;
        const int distance_top_down = 10;

        Size button_size = new Size(50, 50);

        Lotto lotto;
        int[] gezogene_zahlen;

        int anzahl_lottozahlen = 49;

        Color button_default_backcolor = Color.BlanchedAlmond;
        Color button_selected_backcolor = Color.Chartreuse;

        public frmMain()
        {
            InitializeComponent();

            // Button-Array erstellen
            buttons = new Button[anzahl_lottozahlen];

            lotto = new Lotto();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Es werden Buttons automatisch erstellt und positioniert

            this.ClientSize = new Size(buttons_per_row * button_size.Width + (buttons_per_row + 1) * distance_left_right,
                                       buttons_per_column * button_size.Height + (buttons_per_column + 1) * distance_top_down);

            // Könnte man auch per x und y berechnen, so ist es einfacher ;)
            int i = 0;
            for (int y = 1; y <= buttons_per_column; y++)
            {
                for (int x = 1; x <= buttons_per_row; x++)
                {
                    // Button-Objekt erstellen
                    Button b = new Button();
                    b.Size = button_size;
                    int number = (y - 1) * buttons_per_row + x;
                    b.Name = "button" + number.ToString();
                    b.Text = number.ToString();
                    Point location = new Point((x - 1) * button_size.Width + x * distance_left_right,
                                                (y - 1) * button_size.Height + y * distance_top_down);
                    b.Location = location;
                    b.BackColor = button_default_backcolor;
                    b.Click += new EventHandler(buttons_Click);

                    // Dem Controls-Container hinzufügen
                    Controls.Add(b);
                    // In das Array einfügen
                    buttons[i] = b;
                    i++;
                }
            }

            // Alle Buttons sind erstellt
            // Nun Lottozahlen ziehen und anzeigen
            gezogene_zahlen = lotto.zieheLottozahlen();

            färbeButtons();
        }

        private void färbeButtons()
        {
            // Jetzt die Hintergrundfarbe der Buttons ändern
            for (int i = 0; i < gezogene_zahlen.Length; i++)
            {
                buttons[gezogene_zahlen[i] - 1].BackColor = button_selected_backcolor;
            }
        }
        private void buttons_Click(object sender, EventArgs e)
        {
            if (sender is Button)
            {
                Button b = (Button)sender;

                // Hintergrundfarbe der Buttons zurücksetzen
                for (int i = 0; i < buttons.Length; i++)
                {
                    buttons[i].BackColor = button_default_backcolor;
                }

                // Und nun eine neue Ziehung ;)
                gezogene_zahlen = lotto.zieheLottozahlen();
                färbeButtons();
            }
        }
    }
}

Für das Ziehen der sechs Lottozahlen habe ich eine einfache Klasse namens Lotto.cs entworfen, die mittels der Methode zieheLottozahlen():int[] sechs verschiedene Zahlen im Bereich 1 bis 49 zieht und diese als Integer-Array zurückliefert.
Mit Hilfe der beiden Properties AnzahlLottozahlen und AnzahlZiehungen lässt sich der Zahlenbereich und die Anzahl der zu ziehenden Zahlen auch variieren. Altenativ existiert eine zweite Konstruktor-Methode, die die beiden Eigenschaftswerte per Parameter einstellt.

Klassendiagramm aus Visual Studio (nicht UML-konform)

Hier der Programmcode:

using System;

namespace Lottozahlen
{
    public class Lotto
    {

        // Array für Lottozahlen
        // Index 0 wird nicht verwendet!
        // Gezogene Zahlen haben den Wert true
        bool[] lottozahlen;

        // Ergebnisarray
        int[] gezogene_lottozahlen;

        public int AnzahlLottozahlen { set; get; }
        public int AnzahlZiehungen { set; get; }

        // Zufallszahlengenerator
        Random lottozahl = new Random();

        public Lotto()
        {
            AnzahlLottozahlen = 49;
            AnzahlZiehungen = 6;
            lottozahlen = new bool[AnzahlLottozahlen + 1];
            gezogene_lottozahlen = new int[AnzahlZiehungen];
        }

        public Lotto(int lottozahlenanzahl, int ziehungen)
        {
            AnzahlLottozahlen = lottozahlenanzahl;
            AnzahlZiehungen = ziehungen;
            lottozahlen = new bool[AnzahlLottozahlen + 1];
            gezogene_lottozahlen = new int[AnzahlZiehungen];
        }
        public int[] zieheLottozahlen()
        {
            // Ziehen der Lottozahlen
            int i = 0;
            while (i < AnzahlZiehungen)
            {
                // Zufallszahl im Bereich von 1 bis 49
                int neue_zahl = lottozahl.Next(1, 50);

                // neue_zahl ist der Index für das Array
                if (!lottozahlen[neue_zahl])
                {
                    // Gezogene Zahl ist noch nicht gezogen worden
                    lottozahlen[neue_zahl] = true;
                    // In das Ergebnisarray aufnehmen
                    gezogene_lottozahlen[i] = neue_zahl;
                    i++;
                }
            }

            // Ergebnisarray zurück liefern
            return gezogene_lottozahlen;
        }
    }
}

Der nachfolgende Link ermöglicht den Download der Visual Studio Projektmappe.
In der Projektmappe sind drei Projekte, einmal das oben dargestellte, das zweite Projekt ist eine Modifikation des Zahlenlottos „6 aus 49“ (man klickt sechs Zahlen an und erst dann wird eine Ziehung durchgeführt; richtig getippte Zahlen werden dann farbig markiert) und noch ein Projekt mit dem Spiel Tic Tac Toe.