Listbox einer zweiten Form auf Listbox der Hauptform verweisen lassen?

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ray.

    Listbox einer zweiten Form auf Listbox der Hauptform verweisen lassen?

    Hallo,

    mal wieder ne Anfängerfrage zu der ich nichts finden konnte:

    Ich habe in meiner Hauptform eine Listbox und möchte exakt diese Listbox in einer zweiten Form (Form2) angezeigt bekommen, sodass auch Änderungen an der Listbox der zweiten Form in der Hauptform übernommen werden - am Besten also über einen Verweis.

    Dafür habe ich im Editor von Form2 einfach eine Listbox hinzugefügt und übergebe an diese die Listbox der Hauptform bei Erstellen von Form2:

    VB.NET-Quellcode

    1. Public Sub New(ByRef listboxEx As ListBox) ' listboxEx = ListBox der Hauptform
    2. ' Dieser Aufruf ist für den Designer erforderlich.
    3. InitializeComponent()
    4. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    5. ListBox1 = listboxEx
    6. End Sub


    Komischerweise werden die Einträge der Listbox aus der Hauptform nicht in der Listbox1 der zweiten Form angezeigt. Greife ich aber im Debugger Listbox1 ab, existieren sämtliche Items wie in der originalen Listbox, sie werden also schlichtweg nicht angezeigt, sind aber eigentlich da.

    Woran liegt das und wie kann ich sie anzeigen lassen?

    Danke im Voraus und Grüße!
    Der Grund ist, denke ich, dass alle mit dem Designer hinzugefügten Controls in InitializeComponent() initialisiert und hinzugefügt werden.
    Wenn du danach etwas änderst, wird die Änderung evtl. nicht übernommen.
    Kopiere lieber die Items.

    Btw., das ByRef brauchst du in deinem Fall nicht. Wenn du einen Referenztyp als Parameter übergibst, wird die Referenz kopiert, nicht das Objekt.
    Das heißt, du verwendest eine andere Referenz, die aber auf das gleiche Objekt zeigt, da sie nur eine Kopie ist. Wenn du jedoch die übergebene Referenzvariable modifizieren willst (i.e. ihr eine anderes Objektreferenz zuweisen), was du in deinem Fall nicht tust, dann brauchst du ByRef.
    Das wird so denke ich nicht funktionieren. Weil ja auch die Position und Größe der Listbox übergeben wird und auf deiner 2. Form sie ggf. an einer anderen Stelle sitzt.

    Ich würde es so machen, dass wirklich nur die Item-Collection übergibst bzw. zuweist

    VB.NET-Quellcode

    1. ListboxAufForm2.Items = ListBoxEx.Items


    wenn das so funktioniert, es könnte sein das Items ReadOnly ist, dann müsstest du es so machen

    VB.NET-Quellcode

    1. ListboxAufForm2.Items.AddRange(ListBoxEx.Items.ToArray())
    .Items ist readonly und .Toarray() kein Member von .ObjectCollection.

    Ich habs auf deinen Tipp hin mal mit CopyTo versucht, aber da gehts auch nicht weiter, da ich Listbox1.Items nicht als Destination nehmen kann.

    Letztendlich möchte ich, dass Änderungen die in der ListboxForm2 vorgenommen werden ebenso automatisch mit in der ListboxHaupt vorgenommen werden. Momentan lös ich das so, dass ich alle Items rüberkopiere und Änderungen sowohl in die ListboxForm2 als auch in ListboxHaupt einpflege. Quasi doppelte Anzahl von Zeilen pro Änderungen, weswegen mein Gedanke war, dass man das über einen solchen Verweis sicherlich intelligenter lösen kann...
    Das funktioniert problemlos :)

    Nun sind die Items jedoch "bloß" kopiert, es ist also keine Referenz und folglich werden Änderungen an der zweiten Listbox nicht in der Ersten übernommen.
    D.h. es ist kein Unterschied zu dem wie ich es bisher gemacht habe (bevor mir die Idee kam Referenzen zu verwenden). Ich loop halt einfach durch und kopier jedes Item einzeln...

    VB.NET-Quellcode

    1. For Each item In listboxEx.Items
    2. listboxForm2.Items.Add(item)
    3. Next
    du hast einen grundlegenden Denkfehler. Du willst nix an einer Listbox ändern, sondern an Daten willst du etwas ändern.

    Trennung von Gui und Daten beginnt im Kopf.

    Deine Frage ist auch keine Anfängerfrage, sondern erfordert Databinding, und zwar ziemlich listenreiches.
    Man kanns natürlich auch anners frickeln, aber im Databinding-Konzept ist sowas genau vorgesehen.

    Bei Databinding kann man dieselben Daten an verschiedene Controls binden, und alle Controls sind dadurch synchronisiert. Als Controls kannst du DatagridViews nehmen, aber auch Listboxen, nur letztere sind Readonly, und können nur eine Datenspalte anzeigen, was - falls es sich bei den Daten um Tabellen handelt, oft nicht ausreicht.

    Jedenfalls kann man eiglich nichts vernünftiges raten, bevor du nicht erklärst, um was für Daten es sich handelt:
    eine List(Of String)?
    eine DataTable?

    Und dann würde ich empfehlen, zunächstmal ein Databinding innerhalb desselben Forms zu entwickeln, also dass du da erstmal 2 Controls miteinander synchronisiert kriegst.

    Erst im nächsten Schritt täte ich was unternehmen, um die Daten global zugreifbar zu machen, sodass auch controls auf 2 verschiedenen Forms an dieselben Daten gebunden wern können.
    Ok, war mir nicht bewusst, dass das Thema so weit reicht ;).

    In der Listbox stehen die Worksheet-Namen eines Excel Workbooks, also ist nur eine Spalte nötig. Ich möchte es so simpel wie möglich halten - ein DGV ist nicht notwendig, die Listbox ist für mich und auch den User in dem Fall die bessere Wahl.

    Ich werd im Laufe des Tages mal mit Databinding rumspielen, danke dir!
    derselbe Denkfehler - jedenfalls Databindingmäßig gesehen ;).

    Die Worksheetnamen stehen nicht in einer Listbox, sondern in einer List(Of String), die in einer Listbox angezeigt wird.

    VB.NET-Quellcode

    1. Listbox1.DataSource=myWorksheetNameList


    Aber ich habe keine Vorstellung, was man mit so einem primitiven Datenmodell anfangen sollte, und v.a., wofür man bei sonem Primitivling eine über 2 Forms verteilte Präsentation bräuchte.

    Klär mich auf, bitte.
    Ne war nur schlecht ausgedrückt, natürlich ist der Datentyp String.

    Ohne jetzt den Rahmen zu sprengen und das komplette Programm darzustellen (würde ne Weile dauern) - in dem Programm erstellt man Exceldateien aus beliebig vielen Worksheets, mit zig verschiedenen Komponenten. Thematische und funktionelle Unterschiede sind teils in verschiedenen Formen untergebracht. Über das gesamte Programm hinweg soll der User jedoch die Möglichkeit haben, erstellte Excelsheets zu sehen und auch bei Bedarf zu löschen - was über die Listbox geschieht.

    Da gibt es natürlich viele Möglichkeiten - unter anderem versuche ich das auch über eine Hauptform mit "Containerformen" in dieser Hauptform zu lösen (in der Hauptform würde dann permanent diese Listbox stehen), aber ich bin da einfach grad am bisschen am rumprobieren was mir am besten passt und mich hat generell mal interessiert, wie man verschiedene Listboxen synchronisiert - die Frage wurde ja auch dank dir beantwortet ;).
    Das stimmt, aber DGV's bringen so viele Funktionen mit sich die ich nicht brauche, benötigen mehr Platz und Voreinstellungen. Momentan löscht man bequem mit Contextmenu oder "Entfernen"-Taste und bei der durchschnittlichen Sheetanzahl ist das noch vertretbar ;).