Site logo
Site logo
Programmieren aus Leidenschaft
Programmieren aus Leidenschaft

WinForms ohne Baukasten (Teil 2)


Wie Sie im ersten Teil dieser Reihe gesehen haben ist es durchaus möglich Steuerelemente erst nach Programmstart zu erzeugen. Natürlich ist es ebenfalls möglich, ein komplett neues Formular zu erzeugen und mit Steuerelementen zu versehen.
Form myForm = new Form();

Button buttonOK = new Button();
buttonOK.Location = new Point(10, 10);
buttonOK.Size = new Size(75, 25);
buttonOK.Text = "OK";
buttonOK.Click += new System.EventHandler(buttonOK_Click);
myForm.Controls.Add(buttonOK);

myForm.ShowDialog();
Auch "myForm" hat natürlich eine Liste von Steuerelemente an die sich ohne Probleme weitere Objekte hinzufügen lassen. Sogar mehrere Objekte auf ein Mal, wie das nächste Beispiel zeigt.
Form myForm = new Form();
myForm.SuspendLayout();

Button buttonOK = new Button();
buttonOK.Location = new Point(10, 10);
buttonOK.Size = new Size(75, 25);
buttonOK.Text = "OK";
buttonOK.Click += new System.EventHandler(buttonOK_Click);

Button buttonCancel = new Button();
buttonCancel.Location = new Point(10, 40);
buttonCancel.Size = new Size(75, 25);
buttonCancel.Text = "Cancel";

Button buttonDisable = new Button();
buttonDisable.Location = new Point(10, 70);
buttonDisable.Size = new Size(75, 25);
buttonDisable.Text = "Disable";

myForm.Controls.AddRange(new Control[] { buttonOK, buttonCancel,buttonDisable );

myForm.ResumeLayout();

myForm.ShowDialog();
AddRange erlaubt es, mit einem Befehl gleich ein ganzes Array von Steuerelementen (Control) hinzuzufügen. Ebenfalls neu in diesem Beispiel sind die SuspendLayout- und ResumeLayout-Befehle. Diese verhindern, dass die Layoutlogik eines Formulars aktiv wird, solange man noch weitere Objekte hinzufügt. Das Layout Ereignis tritt jedesmal auf, wenn ein Steuerelement neu positioniert wird. Zur Leistungssteigerung läßt sich dieser Vorgang aber unterbinden bis alle neuen Steuerelemente hinzugefügt wurden. Anschließend wird mit ResumeLayout die Logik wieder aktiviert.

Die Steuerelementlisten der Formulare sind eine sehr praktische Sache. Will man zum Beispiel alle Button eines Formulars deaktivieren, so geht das ganz einfach:
foreach(Control c in myForm.Controls)
{
   if(c is Button)
   {
      c.Enabled = false;
   }
}
Eine weitere wichtige Gruppe von Steuerelementen sind die Container. Container haben wenig eigene Funktionen. Sie dienen vielmehr dazu andere Steuerelemente aufzunehmen und das Layout zu vereinfachen. Container können sich auch der Fenstergröße dynamisch anpassen, so dass man sich als Entwickler über die Neupositionierung von Steuerelementen wenig Gedanken machen muß. Einer der wichtigsten Container ist der SplitContainer. Ein SplitContainer besteht aus zwei Panel die entweder vertikal oder horizontal angeordnet sind. In diese Panel können dann weitere Steuerelemente eingesetzt werden. Nachdem dies getan ist wird der SplitContainer dem Formular hinzugefügt.
Button buttonOK = new Button();
buttonOK.Text = "OK";
buttonOK.Dock = DockStyle.Top;

Button buttonCancel = new Button();
buttonCancel.Text = "Cancel";
buttonCancel.Dock = DockStyle.Top;

SplitContainer splC = new SplitContainer();

splC.Orientation = Orientation.Vertical;
splC.Panel1.Controls.Add(buttonOK);
splC.Panel2.Controls.Add(buttonCancel);

splC.Dock = DockStyle.Fill;

myForm.Controls.Add(splC);
In diesem Beispiel wird je ein Button einem Panel hinzugefügt. Was man auf den ersten Blick nicht sieht: Zwischen beiden Panel existiert eine unsichtbare Trennlinie mit der die Größe der Panel verändert werden kann. Bewegt man den Mauspfeil zwischen die Button so ändert sich der Pfeil zu einem Doppelpfeil. Jetzt kann durch klicken und ziehen diese Trennlinie verschoben werden.

Ebenfalls neu in diesem Beispiel ist die Eigenschaft des DockStyle. Sie bestimmt, wie sich das Steuerelement in einem übergeordneten Element andockt. Der SplitContainer hat den DockStyle Wert "fill", was bedeutet, dass er den für ihn verfügbaren Bereich komplett ausfüllt. Da der SplitContainer das einzige Steuerelement direkt auf dem Formular ist, wird er dort den gesamten Platz einnehmen. Die Button hingegen sind mit dem Eigenschaftswert "Top" im SplitContainer angedockt. Dadurch befinden sie sich automatisch am oberen Rand der Panel. Natürlich können auch mehrere Elemente den DockSytle "Top" haben. Sie werden sich dann untereinander anordnen.

Es ist sicherlich ein Manko, dass der SplitContainer nur zwei Panel hat, aber es ist durchaus möglich und auch sinnvoll in einem Panel einen weiteren Container zu verwenden. Außer dem SplitContainer gibt es weitere Steuerelemente, wie das TableLayoutPanel oder das FlowLayoutPanel. Hier sollte man einfach mal seinen Spieltrieb freien Lauf lassen und diese Container ausprobieren. Ihr Verhalten ist sehr unterschiedlich und in verschiedenen Situationen mehr oder weniger vorteilhaft.

Nach meiner Erfahrung wird eine Verschachtelung von Containern selbst im besten Designer irgendwann unübersichtlich. Deshalb bin ich dazu übergegangen bei umfangreichen Anwendungen den DockStyle und die Containerbeziehungen generell im Programmcode selbst zu schreiben. Das erlaubt es mir die Steuerelemente im Designer klein und unabhängig zu lassen, da sie erst nach Programmstart ihre endgültige Größe und Position annehmen.