none
Mehrfacher New() Aufruf RRS feed

  • Frage

  • Liebes Forum,

    ein WindowsForms Projekt besitzt ein Startformular. Aus diesem heraus kann per Klick ein weiteres Formular "MyForm" geöffnet werden, welches wiederum eine Instanz einer anderen Klasse besitzt:

    Public Class MyForm
        Private WithEvents MyOtherClass As New OtherClass
    End Class

    Wenn aus dem Startfomular heraus nun das "MyForm" geöffnet wird:

    Private Sub Button_Klick()
            Dim frmMyForm As New MyForm
            frmMyForm.Show()
    End Sub

    werden die New() Methoden von "MyForm" und "MyOtherClass" jeweils zweimal hintereinander ausgeführt, was nicht sein darf. Wenn ich allerdings "MyForm" direkt als Startformular verwende, werden die New() Methoden beider Klassen jeweils nur einmal ausgeführt.

    Wie kann ich nun "MyForm" aus dem Startformular heraus "richtig" öffnen? Oder wo liegt mein Verständnisproblem?

    Viele Grüße,
    Jan

    Donnerstag, 7. November 2013 11:20

Antworten

  • Hallo Jan,

    wenn Du via Modul Event Handler hinzufügst, so müsste die Methode (hier MyForm.XzyToolStripMenuItem_Click) Shared sein, sonst erzeugt sie implizit eine neue Instanz (mehr ein Überbleibsel von VB Classic als ein Feature).

    Gruß Elmar

    P. S. Man kann Beiträge nachträglich bearbeiten (und mir einen Unerwarteten Fehler ersparen, wenn ich auf zwischenzeitlich gelöschte antworte ;)

    • Als Antwort markiert Jan Kornblum Donnerstag, 7. November 2013 15:43
    Donnerstag, 7. November 2013 15:39
    Beantworter

Alle Antworten

  • Hallo Jan,

    so wie der Code oben zu sehen, ist dürfte die Konstruktor der jeweiligen Klassen (MyForm bzw. OtherClass) nur einmalig ausgeführt werden, und zwar beim Dim frmMyForm As New MyForm. Vermutlich fehlt also irgendwas...

    Um den Verursacher einzugrenzen, füge Debug-Code ein und / oder setze Breakpoints in die Konstruktoren, für oben z. B.:

    Imports System
    
    Public Class MyForm
        Dim WithEvents MyOtherClass As New OtherClass
    
        Public Sub New()
            System.Diagnostics.Debug.WriteLine("MyForm Constructor called")
            InitializeComponent()
        End Sub
    
    End Class
    
    Public Class OtherClass
        Public Sub New()
            System.Diagnostics.Debug.WriteLine("OtherClass Constructor called")
        End Sub
    End Class

    Unabhängig davon: Wenn es Dir darum geht OtherClass nur einmalig zu haben, so sollte man es als Einsatz eines Singleton implementieren.

    Gruß Elmar

    Donnerstag, 7. November 2013 11:32
    Beantworter
  • Hi Elmar,

    wow, das war ja schneller als die Polizei erlaubt ;)

    Mit dem Singleton hast du natürlich recht, das wäre sinnvoll. Aber zunächst muss ich den Fehler finden. Debug Code hatte ich bereits integriert, Ausgabe wie folgt:

    "OtherClass Constructor called"
    "MyForm Constructor called"
    "OtherClass Constructor called"
    "MyForm Constructor called"

    ...wenn ich nur wüsste nach was ich suchen muss!? Im Prinzip muss ja irgendwo im Startformular ein doppeltes Instanzieren von "MyForm" stattfinden, nur die Suche im Code ist erfolglos...

    Grüße, Jan

    Donnerstag, 7. November 2013 12:00
  • Hallo Jan,

    schnell nur, weil ich gerade in dem Moment hier rein geguckt hatte.

    Hast Du mal einen Breakpoint in den Konstruktor gesetzt und dann in die Aufrufliste geguckt? Daraus sollte sich ergeben, wer da noch eine Instanz erzeugt.

    Gruß Elmar

    Donnerstag, 7. November 2013 13:56
    Beantworter
  • eine kleine Idee noch:

    führst Du Button_Klick() programmatisch aus oder, was der Name ja sagt, als Event eines Buttons? Hast Du da vielleicht 2 Event-Quellen zugeordnet (Keypress & Click)?

    Gruß,

    WiWo

    Donnerstag, 7. November 2013 14:47
  • Hi Wiwo,

    das hatte ich auch erst vermutet, war aber nicht so.

    Viele Grüße, Jan

    Donnerstag, 7. November 2013 15:23
  • Hi Elmar,

    die Aufrufliste hat mich tatsächlich weiter gebracht:

    Ich habe ein paar Funktionen in ein Modul ausgelagert. Dort unter anderem eine Funktion:

    Public Sub CreateToolStripMenuXYZ()
       ...
       AddHandler newItem.Click, AddressOf MyForm.XzyToolStripMenuItem_Click
       ...
    End Sub

    Diese Funktion wiederum wir im Load() Event von "MyForm" aufgerufen:

    MyModule.CreateToolStripMenuXYZ()



    Hier wird durch das "AddressOf MyForm.XzyToolStripMenuItem_Click" wohl der New() Konstruktor der Klasse "MyForm" aufgerufen...

    Ich interpretiere das nun so, dass das Load() vor dem New() stattfindet? Klingt aber eher unlogisch...

    Viele Grüße,
    Jan

     


    • Bearbeitet Jan Kornblum Donnerstag, 7. November 2013 15:37
    Donnerstag, 7. November 2013 15:37
  • Hallo Jan,

    wenn Du via Modul Event Handler hinzufügst, so müsste die Methode (hier MyForm.XzyToolStripMenuItem_Click) Shared sein, sonst erzeugt sie implizit eine neue Instanz (mehr ein Überbleibsel von VB Classic als ein Feature).

    Gruß Elmar

    P. S. Man kann Beiträge nachträglich bearbeiten (und mir einen Unerwarteten Fehler ersparen, wenn ich auf zwischenzeitlich gelöschte antworte ;)

    • Als Antwort markiert Jan Kornblum Donnerstag, 7. November 2013 15:43
    Donnerstag, 7. November 2013 15:39
    Beantworter
  • Hallo Elmar,

    super, vielen Dank für deine Hilfe!

    Grüße, Jan

    P.S. Sorry wegen dem Fehler beim Bearbeiten, aber genau aus diesem Grunde habe ich den Beitrag gelöscht: Damit niemand den unvollständigen Beitrag liest, während ich die Korrekturen vornehme - und die Korrektur dann zu spät kommt ;)

    Donnerstag, 7. November 2013 15:43