Ich vermute, dass ausser mir eine ganze Reihe von .NET-Programmieren auch schon in folgender Situation waren: Man muss eine neue Form mit einer ganzen Reihe von Controls definieren im Designer, und für viele der Controls stehen eine Anzahl von Eigenschaften eigentlich schon von Beginn weg fest, und mit der Zeit wünscht man sich, der Designer würde – irgendwie! – diese Eigenschaften gleich beim Erzeugen der Objekte von selbst richtig setzen, so dass man das nicht für x Controls wieder und wieder von Hand selbst tun muss.
Ein Beispiel: Eine Firma arbeitet gewissen Normen punkto Buttons. Sie müssen alle dieselbe, festgelegte Grösse haben, und der Name sei abzuleiten vom Text des Buttons. Wie schön wäre es doch, wenn man dem Designer eine Funktion Erzeuge Standard-Button beibringen könnte, die nach Eingabe des Button-Textes den Button gleich so erzeugt?
Hier würde natürlich ein User Control Standard-Button auch helfen, aber wenn das Szenario nur etwas vielfältiger wird, wie im folgenden Beispiel, ist das kein geeignetes Mittel mehr:
Man portiert eine alte Applikation auf .NET und beginnt mit der Form nicht bei Null, sondern hat im Prinzip die Liste der Controls für die Form schon, als Tabelle in einer Textdatei, mit Namen, Typen und Längen, vom „alten“ Entwicklungs-System her. Es wäre doch schön, diese Tabelle irgendwie im Designer einlesen zu können und für jedes „alte“ Control ein entsprechendes .NET-Control zu erzeugen.
Wie viele Dinge im .NET-Framework geht ein solchermassen Code-gesteuertes Erzeugen von Controls im Designer ziemlich einfach, wenn man den „Kniff“ kennt:
Man schafft sich zuerst die Möglichkeit, eigenen Code im Designer-Kontext laufen zu lassen, z.B. indem man einen System.Windows.Forms.Design.ControlDesigner samt DesignerActionList implementiert, und kann anschliessend neue Controls mit Hilfe des aktiven IDesignerHost-Objekts ganz einfach erzeugen:
IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost)); Button b = (Button)designerHost.CreateComponent(typeof(Button), buttonName);