Problembehandlung bei der Entwurfszeitentwicklung
Im Folgenden sind häufige Probleme aufgeführt, die beim Erstellen einer benutzerdefinierten Entwurfszeitumgebung für Windows Forms-Komponenten und -Steuerelemente auftreten können:
Kompilierung nicht möglich
Debuggen zur Entwurfszeit ist nicht möglich
Compilerfehler: "Der Typ- oder Namespacename 'Typname' konnte nicht gefunden werden."
Entwurfszeitfehler: "Fehler beim Erstellen der Komponente 'Komponentenname'"
Debugfehler: "Unzulässiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement 'Name des Steuerelements' erfolgte nicht von dem Thread aus, in dem das Steuerelement erstellt wurde."
Entwurfszeitfehler: "Für die Datei kann kein Designer geöffnet werden, da die enthaltene Klasse nicht von einer Klasse erbt, die visuell entworfen werden kann."
Nach dem Löschen einer Komponente bleiben Symbole übrig
Das Standardverhalten des Designers wird von benutzerdefiniertem Verhalten verdeckt
Designerereignisse werden unbeabsichtigt ausgelöst
Die Serialisierung von Auflistungen schlägt fehl
Der Designer erhält keinen UndoEngine-Verweis
Änderungen an den Eigenschaften der Komponente werden von der Entwurfsumgebung nicht erkannt
DesignerAttribute-Syntax
Aktualisieren der Entwurfsumgebung, nachdem Änderungen an der Komponente oder dem Designer vorgenommen wurden
FxCop-Warnung auf neu generiertem Windows Form: DoNotInitializeUnnecessarily
Partielle Klassen und der Windows Forms-Designer
Benutzerdefinierte Legacysteuerelemente verursachen unerwartetes Verhalten im Designer
Smarttag in einem gehosteten Designer löst eine Ausnahme aus
Komponentensymbol wird nicht in der Toolbox angezeigt.
Kompilierung nicht möglich
Für einen wesentlichen Teil der Entwurfszeitentwicklung müssen Sie einen Verweis auf die Entwurfszeitassembly System.Design.dll hinzufügen. Diese Assembly ist nicht in .NET Framework 4 Client Profile enthalten. Um einen Verweis auf System.Design.dll hinzuzufügen, müssen Sie das Zielframework des Projekts in .NET Framework 4 ändern.
Debuggen zur Entwurfszeit ist nicht möglich
Es gibt zwei Möglichkeiten, den Entwurfszeitcode zu debuggen:
Fügen Sie an strategischen Punkten im Code MessageBox.Show ein.
Fügen Sie eine andere Instanz von Visual Studio an, um die Entwurfsumgebung der ersten Instanz zu debuggen.
Weitere Informationen finden Sie unter Gewusst wie: Zugriff auf Entwurfszeitdienste.
Compilerfehler: "Der Typ- oder Namespacename 'Typname' konnte nicht gefunden werden."
Sie sollten auf die System.Design-Assembly verweisen. Designerbezogene Typen befinden sich in der System.Design-Assembly. Dies schließt Typen im System.Windows.Forms.Design-Namespace und im System.ComponentModel.Design-Namespace ein.
Zudem müssen Sie die benötigten Namespaces unbedingt mithilfe des Imports-Schlüsselworts oder des using-Schlüsselworts importieren. Weitere Informationen finden Sie unter Gewusst wie: Zugriff auf Entwurfszeitunterstützung in Windows Forms.
Entwurfszeitfehler: "Fehler beim Erstellen der Komponente 'Komponentenname'"
Diese Fehlermeldung erhalten Sie u. U. dann, wenn Sie die Komponente oder das Steuerelement auf der Entwurfsoberfläche über die Toolbox erstellen. In der folgenden Tabelle werden die zwei möglichen Ursachen dieses Fehlers beschrieben.
Ursache |
Beschreibung |
Hinweise |
---|---|---|
Fehlen eines Standardkonstruktors |
Die Komponente oder das Steuerelement muss über einen Standardkonstruktor verfügen, d. h., über einen Konstruktor ohne Parameter. |
Die Entwurfsumgebung benötigt einen Standardkonstruktor, um eine Instanz des Typs erstellen zu können. |
Die Komponente ist ein generischer Typ |
Bei der Komponente oder dem Steuerelement darf es sich nicht um einen generischen Typ (wird auch als Vorlagentyp oder parametrisierter Typ bezeichnet) handeln. Die Entwurfsumgebung unterstützt keine generischen Typen. |
Wenn der generische Typ von UserControl abgeleitet ist und Sie versuchen, ihn im UserControl-Testcontainer von Visual Studio auszuführen, erhalten Sie folgende Fehlermeldung: UserControl 'name' konnte nicht erstellt werden. Die Fehlermeldung lautete "Ein Typ, für den Type.ContainsGenericParameters auf 'true' festgelegt ist, kann nicht erstellt werden." UserControl wird aus der Liste entfernt. Die Komponenten und die Steuerelemente dürfen zwar selbst keine generischen Typen sein, sie können jedoch generische Typen verwenden. |
Entwurfszeitfehler: "Der Wert darf nicht NULL sein.Parametername: 'Komponentenname'"
Diese Fehlermeldung erhalten Sie u. U. dann, wenn Sie die Komponente oder das Steuerelement auf der Entwurfsoberfläche über die Toolbox erstellen. Die wahrscheinlichste Ursache ist der Versuch, eine Komponente oder ein Steuerelement zu verwenden, die bzw. das als Teil einer 64-Bit-Assembly erstellt wurde. Die Visual Studio-Entwurfsumgebung unterstützt keine 64-Bit-Komponenten.
Debugfehler: "Unzulässiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement 'Name des Steuerelements' erfolgte nicht von dem Thread aus, in dem das Steuerelement erstellt wurde."
Wenn Sie Multithreading in Ihrer Windows Forms-Anwendung verwenden, müssen Sie darauf achten, dass Aufrufe der Steuerelemente in threadsicherer Form erfolgen. Diese Ausnahme wird vom Debugger ausgelöst und wird zur Laufzeit nicht erkannt. Es wird jedoch dringend empfohlen, dieses Problem zu beheben, sobald es festgestellt wird. Weitere Informationen finden Sie unter Gewusst wie: Threadsicheres Aufrufen von Windows Forms-Steuerelementen.
Entwurfszeitfehler: "Für die Datei kann kein Designer geöffnet werden, da die enthaltene Klasse nicht von einer Klasse erbt, die visuell entworfen werden kann."
Die Datei mit der Komponente oder dem Steuerelement kann mehrere Klassendefinitionen enthalten, die erste Klasse in der Datei muss jedoch eine Klasse sein, die entworfen werden kann. Die erste Klasse in der Datei muss die IComponent-Schnittstelle implementieren, oder sie muss von einer Component-Klasse oder von einer Klasse, die Component ableitet, abgeleitet sein.
Nach dem Löschen einer Komponente bleiben Symbole übrig
Wenn der benutzerdefinierte Designer Adorner-Objekte erstellt, müssen Sie diese von der Entwurfsoberfläche löschen, sobald der Designer den Gültigkeitsbereich verlässt. Rufen Sie BehaviorServiceAdornerCollection.Remove in der Dispose-Methode des Designers auf, um Glyph-Objekte sowie verknüpfte Adorner-Objekte und Behavior-Objekte zu löschen. Weitere Informationen finden Sie unter Gewusst wie: Erweitern der Darstellung und des Verhaltens von Steuerelementen im Entwurfsmodus.
Das Standardverhalten des Designers wird von benutzerdefiniertem Verhalten verdeckt
Der Standardsteuerelement-Designer erstellt ein Symbol, das das gesamte Steuerelement auf der Entwurfsoberfläche verdeckt. Dieses Symbol wird als Textsymbol bezeichnet. Wenn der benutzerdefinierte Steuerelement-Designer ein Symbol erstellt, das dieselben Begrenzungen wie das Textsymbol aufweist, verdeckt dieses die zugrunde liegende, mit dem Textsymbol verknüpfte Behavior-Implementierung. Dies verhindert die Anzeige von Standardfeatures wie Smarttags und Größenänderungssymbolen.
Sie können keine Meldungen von einem Behavior-Objekt an ein anderes übergeben, daher können Sie bei der Behandlung einer Mausmeldung diese an kein zugrunde liegendes Behavior-Objekt übergeben. Wenn Sie ein Symbol implementieren, das das gesamte Steuerelement verdeckt, sind Sie für die gesamte Darstellung und das Verhalten der benutzerdefinierten Entwurfsumgebung verantwortlich.
Designerereignisse werden unbeabsichtigt ausgelöst
Wenn der benutzerdefinierte Designer Ereignishandler an Designerereignisse anfügt (z. B. ComponentRemoved, ActiveDesignerChanged und SelectionChanged), müssen die Ereignishandler in der Dispose-Methode des Designers getrennt werden.
Andernfalls kann unbeabsichtigtes Verhalten zur Entwurfszeit die Folge sein. In der folgenden Liste sind einige der möglicherweise auftretenden Symptome aufgeführt:
Fehlermeldungsfeld: "Fehler beim Verarbeiten dieses Befehls."
Fehlermeldungsfeld: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."
Beim Löschen von Komponenten oder beim Schließen von Designern werden ungeeignete Ereignishandler aufgerufen.
Die Serialisierung von Auflistungen schlägt fehl
Wenn Sie die Auflistungseigenschaft der benutzerdefinierten Komponente oder des Steuerelements serialisieren möchten, wenden Sie das DesignerSerializationVisibilityAttribute an und legen es auf Content fest. Weitere Informationen finden Sie unter Gewusst wie: Serialisieren von Auflistungen der Standardtypen mit dem DesignerSerializationVisibilityAttribute.
Der Designer erhält keinen UndoEngine-Verweis
Wenn Sie versuchen, einen Verweis auf den UndoEngine-Dienst zu erhalten, während ein Formular geladen wird, gibt die GetService-Methode null zurück.
Der UndoEngine-Dienst wird erst dann erstellt und aktiviert, wenn das Formular vollständig geladen ist. Nach dem Laden des Formulars geben nachfolgende Aufrufe von GetService einen UndoEngine-Verweis zurück.
Ein direkter Verweis auf UndoEngine wird im Allgemeinen selten benötigt. In der Regel werden Situationen, in denen ein solcher Verweis erforderlich ist, durch eine Benutzeraktion ausgelöst und treten nach dem Laden des Designers auf.
Änderungen an den Eigenschaften der Komponente werden von der Entwurfsumgebung nicht erkannt
Wenn Sie Eigenschaften direkt festlegen, werden Änderungen an der Komponente oder dem Steuerelement von der Entwurfsumgebung nicht erkannt. Damit Ereignisse wie ComponentChanged ausgelöst werden, müssen Sie den Wert der Eigenschaften der Komponente mithilfe der PropertyDescriptor.SetValue-Methode festlegen. Dadurch wird der Entwurfsumgebung die Eigenschaftenänderung mitgeteilt, und die Entwurfsoberfläche sowie die PropertyGrid-Steuerelemente können korrekt aktualisiert werden. Weitere Informationen finden Sie unter Gewusst wie: Erweitern der Darstellung und des Verhaltens von Steuerelementen im Entwurfsmodus.
DesignerAttribute-Syntax
Um den benutzerdefinierten Designer an das von ihm entworfene Steuerelement anzufügen, wenden Sie das DesignerAttribute auf das Steuerelement an.
Sie müssen die DesignerAttribute-Parameter genau angeben, da der benutzerdefinierte Designer andernfalls von der Entwurfsumgebung nicht geladen wird.
Aktualisieren der Entwurfsumgebung, nachdem Änderungen an der Komponente oder dem Designer vorgenommen wurden
Wenn Sie Änderungen an den Entwurfszeiteigenschaften einer Komponente vornehmen, müssen Sie das Komponentenprojekt erneut erstellen. Wenn außerdem noch ein weiteres Windows Forms-Projekt geöffnet ist, das diese Komponente verwendet, müssen Sie das Projekt möglicherweise aktualisieren, damit die Änderungen angezeigt werden. In der Regel müssen Sie das Entwurfsfenster, das die Komponente enthält, schließen und erneut öffnen.
FxCop-Warnung auf neu generiertem Windows Form: DoNotInitializeUnnecessarily
Der Windows Forms-Designer generiert den folgenden Code für Windows Forms-Anwendungsprojekte in C#.
private System.ComponentModel.IContainer components = null;
Je nachdem, welche FxCop-Regeln gültig sind, erzeugt FxCop u. U. die Warnung "DoNotInitializeUnnecessarily". Dies geschieht, da es sich bei null um den Standardwert der Common Language Runtime (CLR) für Verweiseigenschaften handelt.
Wenn der Designer das components-Feld nicht auf null initialisiert hat, erzeugt der C#-Compiler die folgende Warnung:
"Zuweisungen für das Feld Form1.components werden nicht ausgeführt. Es hat immer seinen Standardwert von NULL."
Sie können die FxCop-Warnung mit dem SuppressMessageAttribute unterdrücken, dies kann jedoch bei einer Änderung des Klassennamens zu Wartungsproblemen führen. Deshalb wird empfohlen, die FxCop-Warnung lediglich zu ignorieren.
Partielle Klassen und der Windows Forms-Designer
Standardmäßig gibt der Windows Forms-Designer Serialisierungscode in eine bestimmte Datei aus, bei der es sich nicht um die Hauptdatei der Komponente handelt. In einem Windows Forms-Anwendungsprojekt wird z. B. – wie unten dargestellt – die Definition der Form1-Klasse in zwei Dateien aufgeteilt.
Datei (C#-Dateinamen) |
Funktion |
---|---|
Form1.cs |
Hauptklassendatei |
Form1.Designer.cs |
Vom Designer ausgegebener Code |
Datei (VB-Dateinamen) |
Funktion |
---|---|
Form1.vb |
Hauptklassendatei |
Form1.Designer.vb |
Vom Designer ausgegebener Code |
Im Allgemeinen müssen Sie den vom Windows Forms-Designer ausgegebenen Code nicht ändern. Bearbeiten Sie stattdessen die Hauptklassendatei.
Der Windows Forms-Designer verwendet das partial-Schlüsselwort, um die Implementierung von Form1 in zwei separate Dateien aufzuteilen. Dadurch wird eine Durchsetzung des vom Designer ausgegebenen Codes mit dem selbst erstellten Code verhindert. Weitere Informationen zum partial-Schlüsselwort finden Sie unter Partielle Klassen und Methoden (C#-Programmierhandbuch) und Partial (Visual Basic).
Die Aufteilung der Definition eines entwurfsfähigen Typs in mehr als zwei partial-Implementierungen wird vom Windows Forms-Designer nicht unterstützt. Diese Einschränkung schließt das Erstellen einer neuen Klassendatei mit einer dritten partiellen Definition des Typs sowie das Einfügen einer dritten partiellen Klassendefinition des Typs in der Hauptdatei oder der Designerdatei ein. Auf diese Art definierte Member sind im Windows Forms-Designer nicht sichtbar.
Benutzerdefinierte Legacysteuerelemente verursachen unerwartetes Verhalten im Designer
Wenn Typen im Designer ungültig werden, führt ComponentSerializationService einen partiellen Reload aus, um den Designer mit den aktualisierten Typen zu aktualisieren. Bei Versionen von Visual Studio, die älter als Visual Studio 2005 sind, wurde der Designer komplett neu geladen. Der partielle Reload in Visual Studio 2005 ist schneller als ein vollständiger Reload, außerdem bleibt dabei der Rückgängig-Stapel erhalten.
Für Komponenten und entsprechende Serialisierungsprogramme, die vor Visual Studio 2005 erstellt wurden, ist ein partieller Reload unter Umständen nicht möglich. Komponenten und Steuerelemente können zu einem unerwarteten Verhalten führen, da diese so geschrieben wurden, dass sie nur bei einem vollständigen Reload deserialisiert werden. Symptome sind zum Beispiel Stapelüberlauf, Hängen oder leere Bereiche im Windows Forms-Designer, wenn Legacysteuerelemente vorhanden sind.
Sie können festlegen, dass wieder ein vollständiger Reload durchgeführt wird, indem Sie der devenv.exe.config-Datei die folgende Einstellung hinzufügen. Wenn Sie Visual Studio 2005 am Standardspeicherort installiert haben, befindet sich diese Datei im Verzeichnis C:\Program Files\Microsoft Visual Studio 8\Common7\IDE.
<appSettings>
<add key="EnableOptimizedDesignerReloading" value="false" />
</appSettings>
Smarttag in einem gehosteten Designer löst eine Ausnahme aus
Wenn Sie außerhalb von Visual Studio einen Designer hosten, lösen die Smarttags möglicherweise eine NullReferenceException aus. Um dieses Problem zu beheben, stellen Sie im Designer einen IUIService-Verweis bereit und implementieren die Styles-Eigenschaft. Weisen Sie im IDictionary, das von Styles verfügbar gemacht wurde, einen neuen Font als das durch den "DialogFont"-Schlüssel angegebene Element zu. Gehen Sie so vor, wie im folgenden Codefragment gezeigt wird.
Styles["DialogFont"] = new Font(...);
Komponentensymbol wird nicht in der Toolbox angezeigt.
Wenn Sie in Visual Studio ToolboxBitmapAttribute zum Verknüpfen eines Symbols mit der benutzerdefinierten Komponente verbinden, wird in der Toolbox keine Bitmap für automatisch erstellte Komponenten angezeigt. Damit die Bitmap angezeigt wird, müssen Sie das Steuerelement über das Dialogfeld Toolboxelemente auswählen neu laden. Weitere Informationen finden Sie unter Toolboxsymbole.
Siehe auch
Aufgaben
Gewusst wie: Zugriff auf Entwurfszeitdienste
Konzepte
Entwurfszeitfehler im Windows Forms-Designer