Laden...

Von Form abgeleitete Form nicht in VS Designer darstellbar

Erstellt von Cornflake vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.876 Views
C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren
Von Form abgeleitete Form nicht in VS Designer darstellbar

Hallo Leute

In einem Windows C# Programm habe ich ein Formular, dass ich als Basis für weitere Formulare verwenden will. Im Prinzip wie die Verwendung einer abstrakten Klasse.

Bsp:


public partial class BasisFormular : Form
{ ... }

//Andere Datei
public partial class AnmeldeFormular : BasisFormular
{ ... }

//Andere Datei
public partial class EditorFormular : BasisFormular
{ ... }

//Andere Datei
public partial class AbmeldeFormular : BasisFormular
{ ... }

Das Programm läuft, aber wenn ich z.B. das EditorFormular im Visual Studio Formulardesigner öffnen und bearbeite will, bekomme ich die Fehlermeldung:


Der Designer konnte für diese Datei nicht angezeigt werden, da keine der enthaltenen Klassen definiert werden kann. Der Designer hat folgende Klassen in der Datei überprüft: EditorFormular -- Die DeviceApplication1.BasisFormular-Basisklasse konnte nicht geladen werden. Stellen Sie sicher, dass auf die Assembly verwiesen wurde und alle Projekte erstellt wurden. 

Wie kann ich das lösen?

Bisher habe ich bei der MS MSDN Seite nur etwas zu visueller Vererbung gefunden. Aber ich habe nicht vor jetzt nur wegen dem Basisformular ein komplett eigenes Projekt anzulegen und darauf zu verweisen.
gibts da noch ne andere Lösung?

Das gleiche Problem habe ich auch mit der Variante bei UserControls.

Grüße Cornflake

5.658 Beiträge seit 2006
vor 8 Jahren

Hi Cornflake,

in How to: Inherit Windows Forms steht:

In order to inherit from a form, the file or namespace containing that form must have been built into an executable file or DLL.

Christian

Weeks of programming can save you hours of planning

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

Naja also Basisformular und Editorformular befinden sich alle im selben Projekt und Namespace. Das Projekt ist als Exe ausführbar. Ich habe dann noch den Namespace dazugeschrieben, aber bringt nichts.


public partial class BasisFormular : Form
{ ... }
 
//Andere Datei
public partial class EditorFormular : DeviceApplication1.BasisFormular
{ ... }

Anscheindend also doch nur durch seperates Projekt möglich? wäre aber blöd, da im BasisFormular weitere Methoden aufgerufen werden, die ist sonst auch noch alle auslagern muss bzw wieder in ein eigenes Shared Projekt einbauen muss, damit dann alle drei Projekte zusammen arbeiten 😦

5.658 Beiträge seit 2006
vor 8 Jahren

Naja also Basisformular und Editorformular befinden sich alle im selben Projekt und Namespace.

Lies nochmal, was da steht. Ich finde, das ist relativ eindeutig.

wäre aber blöd, da im BasisFormular weitere Methoden aufgerufen werden, die ist sonst auch noch alle auslagern muss bzw wieder in ein eigenes Shared Projekt einbauen muss, damit dann alle drei Projekte zusammen arbeiten 😦

"Wär blöd" ist jetzt irgendwie kein besonders bestechendes Argument. Klingt aber irgendwie nach einer schlecht oder noch nicht durchdachten Software-Architektur...

Christian

Weeks of programming can save you hours of planning

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

Im Prinzip geht ja alles, nur dass der Visual studio Designer nicht mitmacht und ich für Änderungen an der Form immer als Basisklasse vorher "Form" angeben muss, statt "Basisformular".

Aber vllt. muss ich etwas ausholen.

Also es soll das Erzeugungsmuster Objektpool umgesetzt werden. Dazu gibts eine Klasse Formularverwalter, ein enum Formulare und eine Formularvorlage(Basisformular).
Das Basisformular erweitert das Standardformular um eine individuell vergebene FormularID, die einem Eintrag aus dem Enum Formulare entspricht und weitere wiederzuverwendende Methoden.

Zusätzlich werden die Formulare in einer generischen Liste vom Typ der Formularvorlage verwaltet.
Jetzt das Problem. Die Formulare sollen den Formularverwalter veranlassen können, ein bestimmtes anderes Formular aufzurufen. Dazu wird das aufzurufende Formular aus dem enum benannt. Hier etwas Code dazu:


  public enum Formulare
	{
        NULL,
        Anmelden,
        Editor,
        Abmelden,
        ...        
	}


 static class Formmanager
    {
        static List<Basisformular> forms = null;


        public static void Init()
        {

            forms = new List<Basisformular>();

            Basisformular an = new formularAnmelden();
            an.FormularID = Formulare.Anmelden;
            forms.Add(an);

            Basisformular ed = new formularEditor();
            ed.FormularID = Formulare.Editor;
            forms.Add(ed);

            Basisformular ab = new formularAbmelden();
            ab.FormularID = Formulare.Abmelden;
            forms.Add(ab);
 
        }

        public static void Show(Formulare Formular)
        { 
            Show(Formular, Formulare.NULL);
        }

        public static void Show(Formulare Formular, Formulare Previous)
        {
            foreach (Basisformular f in forms)
            {
                if (f.FormularID == Formular)
                {
                    if (Previous != Formulare.NULL)
                    { f.FormularVorheriges = Previous; }
                    f.Visible = true;
                    f.BringToFront();
                }
                else
                {
                    f.Visible = false;
                }
            }
        }

        public static Basisformular GetForm(Formulare Formular)
        {
            foreach (Basisformular f in forms)
            {
                if (f.FormularID == Formular)
                {
                    return f;
                }                
            }

            return null;
        }
    }


public partial class Basisformular : Form
    {
        public Basisformular ()
        {
            InitializeComponent();
        }
 
        public Formulare FormularID;
        public Formulare FormularVorheriges = formulare.NULL;
      ...
}

So ich hoffe das wird jezt nicht zu viel.(Ist nur nen Auszug) Jedenfalls, falls du dazu eine Idee hast, wie ich die Visual Studio Designerunterstützung da miteinbauen kann ohne das Ganze auf verschiedene Projekte aufteilen zu müssen, wäre das super. Es geht ja eigentlich nur um die Designer Fehlermeldung. Oder vllt hast du ein Beispiel, wie man das Pattern besser umsetzen sollte.

F
10.010 Beiträge seit 2004
vor 8 Jahren

Wieso meinst du hat MrSparkle dir das 2 mal gepostet?
Der Designer will eine compilierte Assembly haben wenn du ableitest, und die muss auch instanzierbar sein, also nicht abstract.

Und wenn du bis jetzt noch keine eigenständigen Bibliotheken ( DLLs ) für andere Sachen hast ( Interfaces, BL, DAL usw ) dann solltest du mal langsam damit anfangen.

Und wenn du offensichtlich SW schreibst die im professionellen Umfeld benutzt werden sollen, solltest du dringend etwas zu Architektur lesen, dein Ansatz ist schon Suboptimal.

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

Ok also das mit der Designerunterstützung nur per seperater Assembly ist mir jetzt klar.

Aber abgesehen davon, was ist suboptimal an dem Aufbau mit einer Formularverwaltungsklasse? Ja ich habe mehrere Projekte angelegt. Dieses eine kümmert sich um die Ui bzw. Formularverwaltung.
Hast du einen Link zu einem Beispielaufbau oder Tutorial, dass es erklärt? Aktuell hilft mir da die blanke Kritik ohne konstruktive Hilfe leider nicht weiter.

Grüße Cornflake

5.658 Beiträge seit 2006
vor 8 Jahren

Hast du einen Link zu einem Beispielaufbau oder Tutorial, dass es erklärt?

[Artikel] Drei-Schichten-Architektur

Weeks of programming can save you hours of planning

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

Ok MrSparkle thx
Den Beitrag mit der Schichtentrennung kannte ich schon. An sich ein guter Beitrag, leider geht er nicht auf das Objektpool Pattern ein, bzw. mir fehlt ein C# Beispiel, wie Ihr die Verwaltung von mehreres Formularen handhabt bzw. wie Ihr da das Vorgehen für richtig haltet.

Ich habe übrigens jetzt das mit dem Designer hinbekommen. Selbst wenn man die Vorlage in ein eigenes DLL Projekt auslagert, gabs am Anfang Fehlermeldungen. Aber vllt. für alle die auch vor dem Problem stehen.
Das besondere ist, wenn man den Verweis auf das BasisFormular einbinden, scheint nicht der absolute namespace übernommen zu werden, erst wenn man ein "Geerbtes Formular" Element erstellt und in dem auftauchenden Assistenten die DLL mit dem BasisFormular auswählt, wird der Verweis so eingebunden, dass alle anderen Formulare auch auf einmal auch im VS Designer funktionieren.

Grüße Cornflake

5.658 Beiträge seit 2006
vor 8 Jahren

An sich ein guter Beitrag, leider geht er nicht auf das Objektpool Pattern ein

Das hat ja erstmal nichts miteinander zu tun. Der Artikel bietet einen sehr knappen Einblick in das Thema Software-Architektur. Du kannst nicht erwarten, daß man in einem kurzen Tutorial lernt, wofür andere ein mehrjähriges Studium oder Ausbildung absolvieren. Das Forum ersetzt dir auch nicht, dich selbst damit zu beschäftigen. Es gibt allerdings buchstäblich tausende von Artikeln und Büchern, die dir dabei weiterhelfen sollten.

mir fehlt ein C# Beispiel, wie Ihr die Verwaltung von mehreres Formularen handhabt bzw. wie Ihr da das Vorgehen für richtig haltet.

Hier solltest du dich erstmal mit den zur Verfügung stehenden Datenstrukturen beschäftigen. Eine Liste ist keine Datenstruktur zum Speichern von Schlüssel-Werte-Paaren, dafür gibt es Dictionarys. Und so wie du es implementiert hast, kannst du dir den FormularManager gleich sparen, und statt einem Enum-Wert direkt eine (globale oder nicht-globale) Instanz der Form übergeben. Da du gleich bei Programmstart alle Instanzen erstellst, hat deine Vorgehensweise jedenfalls demgegenüber keinen Vorteil, außer Code, der schlecht wartbar und noch schlechter testbar ist.

Christian

Weeks of programming can save you hours of planning

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

@MrSparkle

Thx für deine Antwort, habe schon dazu (Bücher, Blogs) gelesen, leider nur noch nicht die saubere Version für C# WinForms gefunden.
Eher für ASP.net oder wiedersprüchliche/komplizierte Infos. Z.B. bei MVC wird ein Controllerobjekt von MS angelegt, dass ich aber in VS2008 nirgends finde, oder es werden Instanzen übergeben aber nirgends Events abonniert. Ideal wäre ja eine Webseite auf der für verschiedene Patterns C# Beispielcodes (Solutions) mit kleinem Umfang angeboten werden und in denen noch ein Klassendesigner Objekt die Zusammenhänge verdeutlicht.

Ich werde mal weiter Googeln, DuckDuckGoen und Ixquicken.

T
94 Beiträge seit 2007
vor 8 Jahren

Also wenn du mich fragst, hast du ein Problem in der Basisform. Bedenke, dass beim Laden der geerbten Forms der Designer alle Routinen der Bassiform durchläuft, die beim Laden einer Form nun mal stattfinden (also Konstruktor, Events OnLoad, OnPaint, ...). Schau dir deine Routinen der Basisform mal genauer an. Evtl. knallt es in einer von dieser. Z.B. könnte es ein Problem sein, wenn du beispielsweise im OnLoad-Event auf eine DB zugreifen solltest.

Du kannst im übrigen auch Visual Studio debuggen. Öffne eine zweite Sictzung und attache dich mit der ersten Sitzung.