tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
4372
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    M4st3r M4st3r ist offline Mitglied Brokat
    Registriert seit
    Jan 2005
    Ort
    Frankfurt am Main
    Beiträge
    297
    Hallo Leute,

    folgendes Problem: Ich habe eine MDI-Anwendung die beim starten in einem Verzeichnis alle vorhandene DLL's durchgeht und in diesen nach Windows.Form's, die ein definiertes Interface implementiert haben, sucht. Entsprechende Forms werden in ein dictionary abgelegt, die Form-Caption wird in einen Treeview geschrieben der als Menü dient.

    Soweit so gut. Wenn ich jetzt auf den Eintrag doppelklicke, dann öffnet sich die entsprechende Form als MDI-Child. Wenn ich die Form jetzt über das x schließe und erneut aufrufen will, bekomm ich folgende Exception:

    Auf das verworfene Objekt kann nicht zugegriffen werden.
    Objektname: [Name der Form]
    Klingt so. als würde die Form "zerstört" werden wenn Sie geschlossen wird.

    Wenn ich normalerweise eine Form anzeigen lassen will, funktioniert das ja mit

    Code :
    1
    
    Form frm = new Form();

    Wie mache ich das, wenn ich eine Form aus einer DLL laden?



    Bin dankbar für jede Hilfe und jeden Tipp
     

  2. #2
    M4st3r M4st3r ist offline Mitglied Brokat
    Registriert seit
    Jan 2005
    Ort
    Frankfurt am Main
    Beiträge
    297
    Seltsam, jedesmal wenn ich hier poste, komm ich kurz danach selbst auf die Lösung...

    Für alle die es interessiert:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public void OpenForm(Form frm)
            {
     
                [B]Form form = (Form)Activator.CreateInstance(frm.GetType());[/B]
     
                form.WindowState = FormWindowState.Maximized;
                form.MdiParent = this;            
                form.Show();
            }

    Als Parameter wird die Form aus dem dictionary übergeben. (Form)Activator.CreateInstance(frm.GetType()) erstellt, wie die Funktion schon sagt, eine neue Instanz des Types - et voilá, die Form geht auf, zu, auf, zu, auf...
     

  3. #3
    Avatar von Norbert Eder
    Norbert Eder Norbert Eder ist offline Mitglied Diamant
    Registriert seit
    Feb 2004
    Ort
    Österreich / Graz
    Beiträge
    5.137
    Blog-Einträge
    51
    Du liest die Forms aus deiner DLL und instanzierst sie vermutlich gleich. Mit
    Code :
    1
    
    Form1 muh = new Form1();
    instanzierst du die Form jedes Mal neu. Mit
    Code :
    1
    
    muh.Show();
    kannst du sie anzeigen.

    Du hast insgesamt 2 Möglichkeiten:

    1. Du instanzierst beim Durchgehen deiner Assembly alle Forms, was aber einen hohen Speicherverbrauch hat, vor allem, wenn nicht alle gebraucht werden. Zudem könntest (je nachdem wie komplex deine Forms sind) in ein Window-Handle-Problem laufen. Beim Klicken des Menüeintrags machst du dann ein Form1.Show(). Beim Closing-Event der jeweiligen Formen stoppst du den Schließen-Vorgang und machst einfach nur ein Form1.Hide(), sonst wird sie verworfen und du kannst nicht mehr darauf zugreifen (deine Fehlermeldung).

    2 Du instanzierst die Form dann, wenn auf das entsprechende Menü geklickt wird. So ersparst du dir das Vorhalten der Forms (weniger Speicher), hat jedoch den Nachteil, dass es etwas länger dauert bis die Form sichtbar ist. Zudem müsstest du dir ein anderes Schema überlegen, wie du die Menüpunkte beschriftest etc.

    Hoffe dir geholfen zu haben.
     

  4. #4
    Avatar von Norbert Eder
    Norbert Eder Norbert Eder ist offline Mitglied Diamant
    Registriert seit
    Feb 2004
    Ort
    Österreich / Graz
    Beiträge
    5.137
    Blog-Einträge
    51
    Zitat Zitat von M4st3r
    Seltsam, jedesmal wenn ich hier poste, komm ich kurz danach selbst auf die Lösung...

    Für alle die es interessiert:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public void OpenForm(Form frm)
            {
     
                [B]Form form = (Form)Activator.CreateInstance(frm.GetType());[/B]
     
                form.WindowState = FormWindowState.Maximized;
                form.MdiParent = this;            
                form.Show();
            }
    Als Parameter wird die Form aus dem dictionary übergeben. (Form)Activator.CreateInstance(frm.GetType()) erstellt, wie die Funktion schon sagt, eine neue Instanz des Types - et voilá, die Form geht auf, zu, auf, zu, auf...
    Das ist aber ein umständlicher Weg, weil du so immer mit zwei Objekten des gleichen Typs arbeitest. Das heißt doppelter Speicherverbrauch. Unnötig.
     

  5. #5
    M4st3r M4st3r ist offline Mitglied Brokat
    Registriert seit
    Jan 2005
    Ort
    Frankfurt am Main
    Beiträge
    297
    Auslesen tu ich den ganzen Spass so:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
            public DllProvider(string path)
            {
                Assembly ass = Assembly.LoadFile(path);
     
                foreach (Type t in ass.GetTypes())
                {
                    if (t.GetInterface("IForm") != null)
    this._LoadedForms.Add((Form)Activator.CreateInstance(t));
                }
            }
    Das heißt, ich habe eine Instanz der Form in meiner List<Form>. Mit (Form)Activator.CreateInstance(t) vor dem form.Show bekomm ich eine neue Instanz. Das ist dann das von dir angesprochene Speicher-Problem.

    Im Form_Close Event habe ich schon versucht die Form auf Hide zu stellen, ebenso im Destructor. Beides hat nicht funktioniert. Jedesmal wurde die Form verworfen...

    Ich weiß nicht ob es eine gute Alternative ist, aber ich bin jetzt soweit das ich mir keine Instanz der Form in die Collection lade sondern nur den Type. Beim MDIForm_Load lade ich mir die Types aus den DLL's die eine Form mit dem benötigten Interface habe. Die Menüeinträge erstelle ich, indem ich die List<Type>, in der die Types abgelegt sind, durchlaufe, mir kurz eine Instanz der Form hole, den Menüname auslese und die Form wieder über frm.Dispose kaputt mache.
     

  6. #6
    Avatar von Norbert Eder
    Norbert Eder Norbert Eder ist offline Mitglied Diamant
    Registriert seit
    Feb 2004
    Ort
    Österreich / Graz
    Beiträge
    5.137
    Blog-Einträge
    51
    Im Closing Event hast du natürlich auch EventArgs und dort kannst du Cancel auf true stellen.
     

Ähnliche Themen

  1. form neu laden.
    Von sw0ce im Forum C/C++
    Antworten: 0
    Letzter Beitrag: 27.04.07, 16:06
  2. MC laden und beim draufklicken wieder schließen
    Von Suicider9184 im Forum Flash Plattform
    Antworten: 9
    Letzter Beitrag: 23.11.05, 10:21
  3. Form neu laden
    Von Hiu im Forum Visual Basic 6.0
    Antworten: 1
    Letzter Beitrag: 08.09.05, 18:56
  4. inhalt einer form in eine andere form laden
    Von danielm im Forum Visual Basic 6.0
    Antworten: 3
    Letzter Beitrag: 07.12.03, 11:21
  5. Form laden ...
    Von delPaz im Forum Visual Basic 6.0
    Antworten: 4
    Letzter Beitrag: 19.08.03, 08:35