Announcement

Collapse
No announcement yet.

MyBase.Load - Problem

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MyBase.Load - Problem

    hallo allerseits.
    ich entwickel grad meine erste VB-anwendung.
    ich habe ein hauptformular mit einem Panel.
    in diesem panel starte ich je nach menüauswahl nachgelagerte formulare (siehe codebeispiel)

    [highlight=vbnet]
    Public Sub ShowContainer(ByVal myForm As Form)
    If Not myForm Is Nothing Then
    With myForm
    .TopLevel = False
    .Visible = True
    End With

    With Me.panContainer.Controls
    .Clear()
    .Add(myForm)
    End With
    panContainer.Visible = True
    End Sub
    [/highlight]

    funktioniert soweit auch gut. jetzt stelle ich allerdings fest, das die jeweiligem "MyBase.Load" bereiche der formulare immer nur beim ersten laden durchlaufen werden. ich suche jetzt nach einer möglichkeit, das die programmteile, die im MyBase.Load ablaufen, IMMER laufen - auch wenn das jeweilige formular ein 2. oder 3. mal aufgerufen wird.
    hoffe ich habe mich verständlich machen können und ihr habt MAL WIEDER einen tip für mich VB-anfänger ;-))
    Zuletzt editiert von gfoidl; 30.07.2009, 09:04. Reason: Code-Formatierung hinzugefügt

  • #2
    Wenn ich Deinen Code richtig verstanden habe, lädst Du das Formular gar nicht neu, sondern schaltest nur Visible zwischen True und False. In dem Falle müsstest Du alles, was Du aufrufen willst in den EventHandler von VisibleChanged packen und das in jedem deiner möglichen Formulare.

    [highlight=vbnet]
    Private Sub myFomular_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.VisibleChanged
    MyBase.Load()
    'Einfüllen von Standardwerten
    'Je nach User Eingabefelder sperren
    'Logfile schreiben
    End Sub
    [/highlight]

    Übrigens: ich sehe zwar, dass Du das neue Formular schön bearbeitest, aber was passiert mit dem alten? Das solltest Du vielleicht vernünftig aufräumen, bevor Du das neue ins Panel passt, aber da spricht der C-Programmierer aus mir, der noch ohne GarbageCollector arbeiten musste

    Gruß
    Martin

    Comment


    • #3
      hallo martin,
      danke für den tip. in verbindung mit meinem beispiel oben funktioniert das allerdings nur bedingt. konkret, die VISIBLE_CHANGED-routine wird alleine beim erstmaligen aufruf eines formulares 4mal durchlaufen und danach auch noch einige male.

      ein anderer ansatz von mir war, das jeweils zuletzt verwendete formular VOR dem aufruf eines anderen zu schliessen. bei dieser lösung läuft dann der wiederholte aufruf eines schonmal geöffneten formulares auf einen fehler.

      nur blöd, das mein prototyp schon soweit gediehen ist, das ich nicht einfach eine neue dialogsteuerung bauen kann.

      Comment


      • #4
        kurios...

        hier mal die sub, wie sie funktioniert:
        ---------------------------------------------------------------------------------------------------
        [highlight=vbnet]
        Public Sub ShowContainer(ByVal myForm As Form, ByVal myTitle As String)
        If myForm IsNot Nothing Then
        If currForm IsNot Nothing Then
        currForm.Close()
        currForm.Dispose()
        currForm = Nothing
        End If

        Select case myForm.Name
        case "frmForm1" Then
        currForm = New frmForm1
        case "frmForm2"
        currForm = New frmForm2
        End If

        With currForm
        .TopLevel = False
        .Visible = True
        End With

        With Me.panContainer.Controls
        .Add(currForm)
        currForm.Show()
        End With
        panContainer.Visible = True
        end if
        end sub[/highlight]

        jetzt die version, wo der erstmalige aufruf einer form funktioniert, aber
        der 2. aufruf einer form, die schonmal geladen war, NICHT mehr funktioniert:
        -------------------------------------------------------------------------------------------------
        [highlight=vbnet]
        Public Sub ShowContainer(ByVal myForm As Form, ByVal myTitle As String)
        If myForm IsNot Nothing Then
        If currForm IsNot Nothing Then
        currForm.Close()
        currForm.Dispose()
        currForm = Nothing
        End If

        currForm = New Form 'wenn ich hier sage "currform = new myForm"
        'gibts den fehler: "typ myForm ist nicht definiert
        currForm = myForm
        With currForm
        .TopLevel = False
        .Visible = True
        End With

        With Me.panContainer.Controls
        .Add(currForm)
        currForm.Show()
        End With
        panContainer.Visible = True
        end if
        end sub[/highlight]

        ich möchte halt erreichen, nicht nochmal meine komplette form-liste hier "hart" reinzuschreiben und dann über eine select case struktur anzusteuern.
        Zuletzt editiert von gfoidl; 30.07.2009, 09:04. Reason: Code-Formatierung hinzugefügt

        Comment


        • #5
          Hallo tioga63,

          wenn du den Code entsprechend formatieren würdest könnte dir leichter geholfen werden.


          mfG Gü
          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

          Comment


          • #6
            Originally posted by gfoidl View Post
            Hallo tioga63,

            wenn du den Code entsprechend formatieren würdest könnte dir leichter geholfen werden.


            mfG Gü
            ok ok, danke für den tip.
            so besser ? (siehe oben) ;-))

            Comment


            • #7
              myForm ist keine Klasse sondern ein Parameter deiner ShowContainer Methode.
              Man kann natürlich mit new nur aus Klassen neue Instanzen erzeugen.

              Aber was soll das überhaupt? Du übergibst die myForm Instanz an die Methode wieso benutzt du die nicht einfach? Wenn du immer eine neue Instanz haben willst solltest du keine bereits vorhandene Instanz an die Methode übergeben sondern nur die Klasse. Das geht am einfachsten als generische Methode.

              [Highlight=VB.NET]
              Public Sub ShowContainer(Of T As {Form, New})(ByVal myTitle As String)
              'dein Code zum löschen einer alten Form
              currForm = New T
              'dein Code zum anzeigen von currForm
              End Sub

              'Aufrufbeispiel
              ShowContainer(Of frmForm1)("meinTitel")
              [/Highlight]

              Comment


              • #8
                hallo ralf,
                danke für deine ausführungen!! ich sollte vielleicht dazu schreiben, das dies mein erstes projekt in sachen vb.net ist.

                folgende rahmeninfo noch zu meinem problem.
                ich habe ein zentrales hauptformular mit einem treeview-menü auf der linken seite. in dem treeview sind die nodes bzw. subnodes als object-arrays definiert.
                beispiel (auszug):
                [highlight=vbnet]
                Dim arrNodes() As String = {"Formular1", "Formular2", "Formular3"}
                Dim arrSubNodes1() As Object = {frmFormA.Text, frmFormA}

                Dim tvNode As TreeNode = myTreeView.Nodes.Add(arrNodes(iTN))
                arrSubNodesCount = arrSubNodes1.GetLength(0) - 1
                SubTn = tvNode.Nodes.Add(arrSubNodes1(iSN))
                newForm = arrSubNodes1(iSN)
                SubTn.Tag = newForm

                Public Sub TreeView_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TVMenu.AfterSelect
                ShowContainer(Of e.Node.tag)(e.Node.Text)
                End Sub
                [/highlight]
                ...

                jetzt möchte ich bei click auf einen subnode im treeview eben über meine methode ShowContainer.... die jeweilige form in einem panel rechts neben dem treeview öffnen. zu übergeben wäre also beim aufruf die in SubTn.Tag hinterlegte Form.

                ...was natürlich nicht funktioniert... ;-))
                Zuletzt editiert von tioga63; 30.07.2009, 10:39.

                Comment


                • #9
                  Um den Tree zu befüllen könntest du folgendermaßen vorgehen. So hängt im Anschluß in den Tags der Nodes der Klassentyp deiner Formulare.

                  [Highlight=VB.NET]Dim arrNodes() As String = {"Formular1", "Formular2", "Formular3"}
                  Dim arrNodeTypes() As Type = {GetType(frmFormA), GetType(frmFormB), GetType(frmFormC)}

                  Dim tvNode As TreeNode
                  For Each nodeName As String In arrNodes
                  tvNode = myTreeView.Nodes.Add(nodeName)
                  tvNode.Tag = arrNodeTypes(tvNode.Index)
                  Next[/Highlight]

                  So funktioniert aber die angedachte Version mit einer generischen Methode nicht mehr. Als generischen Parameter musst du einen konkreten Typ benennen du kannst dort leider keine Variable angeben. Also ShowContainer(Of e.Node.tag) geht nicht. Deshalb brauchen wir dann eine normale nicht generische Variante der Methode.


                  [Highlight=VB.NET]Public Sub ShowContainer(ByVal myFormType As Type, ByVal myTitle As String)
                  'dein Code zum löschen einer alten Form
                  currForm = Activator.CreateInstance(myFormType)
                  'dein Code zum anzeigen von currForm
                  End Sub

                  Private Sub myTreeView_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles myTreeView.AfterSelect
                  ShowContainer(e.Node.Tag, e.Node.Text)
                  End Sub[/Highlight]

                  Aber Vorsicht da jetzt der Typ der Klasse myFormType nicht geprüft wird könnte man da alles übergeben eben auch Dinge die keine Form sind. Das knallt dann natürlich bei der Zuweisung zu currForm. Korrekterweise müsstest du noch eine Prüfung in ShowContainer einbauen das myFormType auch wirklich ein Abkömmling von Form ist und gegebenenfalls eine Exception werfen.

                  Wofür benutzt du eigentlich myTitle?

                  Comment


                  • #10
                    hallo ralf,
                    mensch - vielen dank für diese lösungsansätze.
                    werde ich morgen vormittag sofort ausprobieren.
                    das sind jetzt allerdings schon tiefste tiefen von vb.net für mich.

                    wofür ich myTitle verwende?
                    ich wollte darüber in einem header-panel dem nutzer anzeigen, welcher menüpunkt gerade aktiviert und ausgewählt ist.
                    kam bei einer zurückliegenden access-anwendung ganz gut an.
                    wollte ich daher übernehmen.

                    ich halte dich natürlich auf dem laufenden.

                    gruss und danke
                    ronald

                    Comment


                    • #11
                      hallo und guten morgen ralf,

                      es ist vollbracht. dank deiner hilfe läuft die menüsteuerung und formularübergabe an ein container-panel einwandfrei.

                      VIELEN DANK !!!!
                      gruss und angenehmes we
                      R.

                      hier abschliessend mal der code, so wie es funktioniert:

                      [highlight=vbnet]
                      'Aufbau des Treeview
                      '------------------------------------------------------------------------
                      Private Sub build_Menu(ByVal myTreeView As TreeView)
                      Dim tvNode As TreeNode, SubTn As TreeNode, _
                      arrN() As String, arrSN() As String, arrSNT() As Type

                      Dim arrNodes() As String = {"Bereich 1", _
                      "Bereich 2"}

                      Dim arrSubNodes1() As String = {"Formular 1", _
                      "Formular 2", _
                      "Formular 3", _
                      "Formular 4", _
                      "Formular 5", _
                      "Formular 6"}

                      Dim arrSubNodes1Types() As Type = {GetType(frmA), _
                      GetType(frmB), _
                      GetType(frmC), _
                      GetType(frmD), _
                      GetType(frmE), _
                      GetType(frmF)}

                      Dim arrSubNodes2() As String = {"Formular 7"}
                      Dim arrSubNodes2Types() As Type = {GetType(frmG)}

                      For Each nodeName As String In arrNodes
                      tvNode = myTreeView.Nodes.Add(nodeName)
                      arrSN = Nothing
                      arrSNT = Nothing

                      Select Case tvNode.Index
                      Case 0
                      arrSN = arrSubNodes1
                      arrSNT = arrSubNodes1Types
                      Case 1
                      arrSN = arrSubNodes2
                      arrSNT = arrSubNodes2Types
                      Case 2
                      If appUserTraeger = "99" Then
                      arrSN = arrSubNodes3
                      arrSNT = arrSubNodes3Types
                      End If
                      End Select

                      If arrSN IsNot Nothing Then
                      For Each subNodeName As String In arrSN
                      SubTn = tvNode.Nodes.Add(subNodeName)
                      SubTn.Tag = arrSNT(SubTn.Index)
                      Next
                      End If
                      Next
                      End Sub

                      '------------------------------------------------------------------------
                      'Aufruf eines Formulars aus dem TreeView-Menü
                      '------------------------------------------------------------------------
                      Public Sub TreeView_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TVMenu.AfterSelect
                      ShowContainer(e.Node.Tag, e.Node.Text)
                      End Sub


                      '------------------------------------------------------------------------
                      'Methode zur Anzeige des jeweiligen Formulars im Container-Panel
                      '------------------------------------------------------------------------
                      Public Sub ShowContainer(ByVal myFormType As Type, ByVal myTitle As String)
                      If currForm IsNot Nothing Then
                      currForm.Close()
                      currForm.Dispose()
                      currForm = Nothing
                      End If

                      currForm = Activator.CreateInstance(myFormType)
                      With currForm
                      .TopLevel = False
                      .Visible = True
                      End With

                      With Me.panContainer.Controls
                      .Add(currForm)
                      currForm.Show()
                      End With
                      panContainer.Visible = True
                      End Sub
                      [/highlight]

                      Comment


                      • #12
                        guten abend allerseits,
                        jetzt muss ich diesen "fred" doch nochmal reaktivieren.

                        die angegebene lösung der formularsteuerung über die CREATEINSTANCE-thematik funktioniert nachwievor einwandfrei.

                        jetzt gibt es allerdings eine ergänzung in einer weiteren anwendung, wo ich nach auswahl einer testperson über einem treeview-eintrag zunächst in einem panel neben dem treeview das entsprechende formular anzeige.

                        wenn ich jetzt die nächste person im treeview auswähle möchte ich nicht jedesmal das formular neu laden.
                        ich bin soweit, das die ermittlung der personendaten korrekt durchlaufen wird, die felder des formulares sind auch im zugriff und - lt. sichtung im debugger - korrekt gefüllt.
                        sehen tue ich aber immer nur die vorhergehende person im formular.

                        wie kann das denn sein?

                        Comment

                        Working...
                        X