W czasie pracy nad swoim małym projektem w C#, stanąłem przed problemem dynamicznego generowania kontrolek na formie. Nie chciałem, aby cały kod za to odpowiedzialny znajdował się w zdarzeniu kliknięcia w button, wiec stworzyłem przykładową klasę, którą nazwałem ControlGenerator.
![]()
Generalnie, trzeba by ją jakoś połączyć z główną formą aplikacji (w projekcie Form1 – standardowe nazewnictwo, gdyż więcej form nie przewiduję). W klasie ControlGenerator utworzyłem zmienną typu Form1 służącą za łącznik klasa – forma:
public class ControlGenerator
{
/// Prywatna zmienna typu Form1
private Form1 pf;
//...
}
Następnie, konstruktor klasy musi posiadać takie przypisanie zmienej pf, aby wskazywała ona na referencję instancji mojej Form1 (trochę to może zamieszane, więc kawałek kodu wyjaśni, co miałem na myśli):
public ControlGenerator(Form1 f1)
{
pf = f1;
}
Tak właśnie wygląda konstruktor, o którym była mowa, a jak to wygląda ‘na żywo’ jest ukazane poniżej.
W formie głównej aplikacji (Form1) po kliknięciu w jeden z przycisków powinny wygenerować się kontrolki, inicjuję więc obiekt klasy ControlGenerator w następujący sposób:
private void button1_Click(object sender, EventArgs e)
{
ControlGenerator generate = new ControlGenerator(this);
// właśnie tu do konstruktora przekazuje referencję do Form1 za pomocą this
}
Skoro moje połączenie klasa – forma jest już aktywne, to pora napisać metodę generującą kontrolki. Do owej metody powinna być przekazana informacja jak wiele kontrolek utworzyć. W poniższym przykładzie ograniczę się do wygenerowania TextBoxów z Labelkami zawartymi w GroupBoxie (które mogą być oczywiście dodatkowo osadzone na jakimś panelu, czy czymkolwiek się chce).
Gotowa funkcja prezentuje się następująco:
public void GenerateRegisterControls(int number, string text)
{
int[] textboxes = new int[number];
string[] labels = { "Imię", "Nazwisko", "PESEL", "Ulica", "Numer budynku",
"Miasto", "Kod pocztowy", "Województwo", "Telefon" };
int i = 0, move = 0;
//tworzę GroupBoxa, do którego wrzucę tworzone kontrolki (opis metody w następnym listingu)
GroupBox box = GenerateGroupBoxControl(text);
foreach (int element in textboxes)
{
TextBox textbox = new TextBox(); //tworzę nowego TextBoxa
Label label = new Label(); //tworzę nowy Label
//lokalizacja TextBoxa
textbox.Location = new System.Drawing.Point(200, 70 + move);
textbox.Name = "textbox" + i.ToString();
textbox.Size = new System.Drawing.Size(360, 20 + move); //wymiary TextBoxa
//Rozmiar czcionki w TextBoxie - funkcja nie zostanie przedstawiona
//w tym wpisie
textbox.Font = SetFontForElement(40, textbox.Font);
textbox.TabIndex = i;
textbox.Visible = true;
//automatyczna zmiana rozmiarów TextBoxa przy zmianie rozmiaru okna
textbox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
textbox.BorderStyle = BorderStyle.FixedSingle; //styl ramki
//lokalizacja Labela
label.Location = new System.Drawing.Point(20, 80 + move);
label.Name = "label" + i.ToString();
//nazwa Labela wzięta z wcześniej utworzonej tablicy stringów
label.Text = labels[i];
label.Font = SetFontForElement(28, label.Font);
label.Size = new System.Drawing.Size(160, 28);
label.Visible = true;
box.Controls.Add(textbox); //dodaję do GroupBoxa utworzone TextBoxy
box.Controls.Add(label); //dodaję do GroupBoxa utworzone Labele
i++;
move += 50;
}
//dodaję GroupBoxa z kontrolkami do panelu w kontenerze Form1
pf.splitContainer1.Panel2.Controls.Add(box);
}
Jak widać funkcja nie jest specjalnie skomplikowana, a tablicę z nazwami labelek można by przekazać jako parametr – jednak nie ma potrzeby w tym wpisie rozmieniać się na drobne. Tworzenie TextBoxów i Labelek można by dodatkowo zostawić osobnym funkcjom wywołanym w GenerateRegisterControls, jak np. GenerateGroupBoxControl, która wygląda następująco:
private GroupBox GenerateGroupBoxControl(string text)
{
GroupBox box = new GroupBox();
box.Name = "GroupBoxRegister";
box.Text = text;
box.Location = new System.Drawing.Point(1, 9);
box.Size = new System.Drawing.Size(pf.splitContainer1.Panel2.Width - 20, pf.splitContainer1.Panel2.Height - 20);
box.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
return box;
}
Samo wygenerowanie kontrolek po kliknięciu w jeden z przycisków wygląda następująco:
private void button1_Click(object sender, EventArgs e)
{
ControlGenerator generate = new ControlGenerator(this);
//9 TextBoxów i 9 Labelek, GroupBox będzie opatrzony tekstem Rejestracja
generate.GenerateRegisterControls(9, "Rejestracja");
}
Jeśli ktoś dopiero zaczyna swoją przygodę z C#, to informacje, które przedstawiłem z pewnością się przydadzą, albo przynajmniej wskażą drogę poszukiwań w google. AVE!

0
komentarzy