Änderung eines Labels in einer Child Form per Timer

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Änderung eines Labels in einer Child Form per Timer

    Guten Tag,

    ich habe eine Form in der ein MDIChild Fenster angezeigt wird. Bisher war es so:

    - Hauptform hat einen Clock Timer zur Anzeige der Uhrzeit in der eigenen Statusleiste
    - Childform hat ebenfalls einen Timer zur Uhrzeitanzeige in einem großen Label

    Nun wollte ich etwas sparen und habe die Anzeige für die Child Form mit in den Timer der Hauptform gepackt:

    VB.NET-Quellcode

    1. frm_mainmenu.lbl_date.Text = My.Computer.Clock.LocalTime.ToShortDateString


    Leider wird aber die Anzeige des Labels nicht mit der Uhrzeit gefüllt. Ich habe für dieses Label den "Modfier" auch mal auf "public" gesetzt, hat aber nichts geändert.

    Bin dankbar für jeden Tipp.
    ==> seid .net zueinander :D <3 <==
    @Axxxxxl Wie sah denn die offensichtlich funktionierende vorherige Lösung aus?
    Setz mal einen Haltepunkt auf die Zeile und überzeuge Dich, dass der richtige Text eingetragen wird.
    Wahrscheinlich wird der Text in einer anderen Prozedur einfach nur mit einem Leerstring überschrieben.
    Finde diese Stelle: Rechter Mausklick - Alle Verweise suchen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vorher war die Codezeile

    VB.NET-Quellcode

    1. lbl_date.Text = My.Computer.Clock.LocalTime.ToShortDateString

    lediglich in einem Timer, welcher direkt auf der Childform war. Ich habe diese Zeile nun lediglich in den Timer der Hauptform kopiert und dort noch das "frm_mainmenu." davorgesetzt, weil sich das Label ja auf dem Unterformular befindet. Dort gibt es nirgendwo mehr Verweise welche das Label ansprechen würden.

    Irgendwie scheint da eine "Barierre" zwischen den Formen zu sein?!
    ==> seid .net zueinander :D <3 <==
    Ich denke ich habe eine Erklärung?!
    SO rufe ich das Child Fenster aus dem Hauptfenster auf:

    VB.NET-Quellcode

    1. '***Hauptmenü laden
    2. Dim NewMDIChild As New frm_mainmenu()
    3. 'Set the Parent Form of the Child window.
    4. NewMDIChild.MdiParent = Me
    5. 'Eigenschaften des neuen Unterfenster setzen
    6. NewMDIChild.Anchor = AnchorStyles.Left
    7. NewMDIChild.Anchor = AnchorStyles.Top
    8. 'Display the new form.
    9. NewMDIChild.Show()
    10. NewMDIChild.Dock = DockStyle.Fill


    Ich denke, es liegt daran, dass diese Unterform "frm_mainmenu" immer eine eigene Instanz hat wenn sie aufgefrufen wird und deswegen keine Daten direkt an sie übergeben werden können?! Aber da ich bin ich zu wenig Profi bei dem Thema.
    Ich lasse nun den Timer erstmal auch noch in der Unterform laufen.

    Vielleicht hat noch einer eine Idee?!
    ==> seid .net zueinander :D <3 <==
    @Axxxxxl Das denke ich nicht.
    Mach Dir mal ein kleines neues Testprojekt mit MDI und einer Child-Form zur Anzeige und nem Timer in der Hauptform, wo Du das ganze mal separat austesten kannst.
    ====
    NewMDIChild.Anchor kannst Du löschen, das wird von Dock = Fill überschrieben.
    ====
    Wer ist das Parent von lbl_date?

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    das lbl_date befindet sich auf dem MDIChild "frm_mainmenu". Der Timer sitzt auf dem Hauptfenster "frm_main".
    Ich habe gerade gemerkt, dass nichts vom Hauptfenster im MDI Child ankommt. Ich habe im Hauptfenster einen Testbutton gemacht und lasse den "frm_mainmenu.lbl_date.text = "Test" ausführen. Es passiert auch hier nichts.
    ==> seid .net zueinander :D <3 <==
    @Axxxxxl Kopiere mal das Projekt. Specke es völlig ab, so dass nur noch diese Rumpf-Funktionalität drin ist.
    Überzeuge Dich davon, dass es compiliert und häng es bereinigt (ohne obj- und bin-Verzeichnisse als ZIP an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich werf mal nen Spekulatius in den Ring: Nachdem der Instanziierungsfehler aus Post#1 zu Post#4 behoben wurde (frm_mainmenu.lbl_date.Text = , frm_mainmenu ist laut Post#4 ein Klassenname), wird in Post#4 zwar das MDI-Child korrekt aufgebaut. Aber dieser Code funktioniert nur innerhalb einer Sub. Und daher ist bei Post#4, Z#2 an der Stelle lokal NewMDIChild bekannt. Aber später im Timer_Tick nicht mehr. Da frag ich mich doch glatt, was da in der Timer_Tick-Prozedur alles genau drinsteht, um die Uhrzeit im MDI-Child anzuzeigen. Dies (auch) mal bitte posten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo,

    sorry für die verspätete Antwort. Also das ganze Projekt nur auf die Codezeilen des Aufrufs im fremdem Fenster runterbrechen geht echt nicht, da blicke ich nicht mehr durch sonst.
    Ich habe es aber gerade so gegen getestet, dass ich mir eigentlich sicher bin, dass es daran liegen muss dass das Unterfenster frm_mainmenu ja bei jedem Aufruf neu aufgebaut wird mit der Prozedur
    Spoiler anzeigen

    VB.NET-Quellcode

    1. '***Hauptmenü laden
    2. Dim NewMDIChild As New frm_mainmenu()
    3. 'Set the Parent Form of the Child window.
    4. NewMDIChild.MdiParent = Me
    5. 'Display the new form.
    6. NewMDIChild.Dock = DockStyle.Fill
    7. NewMDIChild.Show()


    Ich habe jetzt mal auf einem Button im Hauptfenster frm_main (was ja immer da ist) den Code gelegt:

    VB.NET-Quellcode

    1. MessageBox.Show("Label Date heißt: " & frm_mainmenu.lbl_date.Text)

    Wenn ich das aufrufe, zeigt er mir an, dass in diesem Label der Text "Date" stehen würde. Das stimmt auch soweit, denn das habe ich in der Entwicklungsumgebung des Unterformulars frm_mainmenu auch tatsächlich so drin stehen. Aber eigentlich sollte er ja im "Livebetrieb" dann das dort per Timer angezeigte heutige Datum auslesen?

    Somit die Frage: Wie komme ich an die aktuelle Instanz dieses Unterformulars "frm_mainmenu"?!?
    ==> seid .net zueinander :D <3 <==

    Axxxxxl schrieb:

    dass es daran liegen muss
    Dann erstell ein kleines Testprojekt mit diesem Snippet und überzeuge Dich, dass es so ist.
    Wenn es tatsächlich so ist, poste das Testprogrämmchen ohne bin- und obj-Verzeichnisse als ZIP.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wie bereits in Post#8 geschrieben: NewMDIChild ist nur lokal in der Sub frm_main_load bekannt. Und daher kommt in der Button1_Click-Sub Mus raus, wenn Du dann schreibst:

    VB.NET-Quellcode

    1. MessageBox.Show("Text in Label Date in Unterform ist: " & Form1.lbl_date.Text)
    Denn NewMDIChild und Form1 sind nicht das selbe! Daher deklarier NewMDIChild klassenweit, also nicht innerhalb einer Sub. Also: Die Zeile Dim NewMDIChild As New Form1 kommt direkt vor die Zeile Private Sub frm_main_Load(sender As Object, e As EventArgs) Handles MyBase.Load. Und wenn Du dann noch in der Button1_Click-Sub das Form1 durch NewMDIChild ersetzt, greift diese MessageBox-Zeile nicht mehr auf ein ominöses Formular zurück, sondern plötzlich auf das von Dir konkret instanziierte Objekt NewMDIChild, wo die Zeit angezeigt und aktualisiert wird. Schreib also

    VB.NET-Quellcode

    1. Dim NewMDIChild As New Form1
    2. Private Sub frm_main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. 'MDI Child laden
    4. 'Set the Parent Form of the Child window.
    5. NewMDIChild.MdiParent = Me
    6. 'Display the new form.
    7. NewMDIChild.Dock = DockStyle.Top
    8. NewMDIChild.Show()
    9. End Sub
    10. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btn_text.Click
    11. MessageBox.Show("Text in Label Date in Unterform ist: " & NewMDIChild.lbl_date.Text)
    12. End Sub

    Und schon geschieht, was Du willst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Axxxxxl Deine Herangehensweise ist falsch.
    Fas Hauptfenster hat nicht ein Unterfenster nach irgend einem wert zu fragen, sondern das Unterfenster meldet dem Hauptfenster den Wert per Event.
    @VaporiZed Wir haben hier MDI, da ist es nicht erforderlich, dass die Instanz der Form1 in der Klasse gehalten wird, denn bei MDI ist es ja explizit vorgesehen, dass "beliebig viele" Instanzen der Form1 erzeugt werden können. Und das geht nur, wenn die Instanz lokal erzeugt wird.
    Die Abfrage geht dann so (ohne Test auf Existenz):

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btn_text.Click
    2. Dim dlg As Form1 = CType(Application.OpenForms(1), Form1)
    3. MessageBox.Show("Text in Label Date in Unterform ist: " & dlg.lbl_date.Text)
    4. End Sub

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ob man jetzt pulling oder pushing verwendet, ist situationsabhängig. Ne Hauptform-MessageBox per Value-pushing mittels Event mit Daten zu versorgen, halte ich jedoch für … ineffektiv. Und: Du verwendest in Deinem Code ja auch pulling und kein Event raising.
    Bezüglich MDI-Instanz: Da wollte ich explizit auf das Missverständnis hinweisen, dass der TE NewMDIChild und Form1 als identisch ansieht, was aber nicht so ist.

    ##########

    btw: Ich würde auf das Child so zugreifen:

    VB.NET-Quellcode

    1. DirectCast(Me.MdiChildren(0), Form1)

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Hallo die Herren,

    danke für die Antworten, auch wenn das für mich schon leicht ins "Häää?!" abschweift zwecks fehlenden Wissen.
    Jedenfalls hat

    VB.NET-Quellcode

    1. Dim dlg As Form1 = CType(Application.OpenForms(1), Form1)
    2. MessageBox.Show("Text in Label Date in Unterform ist: " & dlg.lbl_date.Text)

    funktioniert so wie es soll. Dazu aber die abschließende Frage, wie gestalte ich nun den Aufruf in meinem "richtigen" Programm per Timer im Hauptformular der die SUB im Unterformular aufrufen soll!?
    ==> seid .net zueinander :D <3 <==
    @Axxxxxl In Deinem richtigen Programm sollte das MDI-Child die Information per Event an das Hauptfenster senden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Du meinst wenn wir bei dem Beispiel mit dem Label bleiben?
    Ich habe aber doch im MDI Child die SUB geschrieben, welche ein Datagrid füllt aus einer Exceltabelle. Diese Sub soll nun vom 15-Minuten Timer des Haupformulars aufgerufen werden. Hat das dann trotzdem mit einem "Event des MDI Childs" zu tun?!
    ==> seid .net zueinander :D <3 <==

    Axxxxxl schrieb:

    Diese Sub soll nun vom 15-Minuten Timer des Haupformulars aufgerufen werden.
    Falsch.
    Alle 15 Minuten macht die Form iwas und teilt dem Hauptfenster per Event das Ergebnis mit, gugst Du Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich verstehe dich schon @RodFromGermany aber das würde ja heißen, dass ich dazu auch auf dem MDI Child welches die Funktion enthält wieder einen 15sek Timer installieren müsste. Und genau das wollte ich ja vermeiden, weil es im Hauptformular schon einen 15sek Timer gibt, welcher dort Dinge für das Hauptformular ausführt. Und genau diesen wollte ich mit nutzen, um die Routine des MDI Child aufrufen zu lassen.

    Aber wenn es keine extremem Ressourcen verschwendet, spendiere ich dem MDI auch noch nen Timer?!
    ==> seid .net zueinander :D <3 <==
    @Axxxxxl logisch gehört der Timer nur in das MDI-Child.
    Was macht er denn sonst noch so?
    OOP - Trennung von Inhalten.
    Wenn die Timer disjunkte Sachen antriggern, muss man ggf. mehrere Timer verwenden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!