Zweites Form soll gleiche Tabelle abbilden

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

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Zweites Form soll gleiche Tabelle abbilden

    Hallo,

    Also mit zwei bzw. mehreren Forms hantieren hab ich immer noch nicht drauf.
    Das macht mit dem Beispiel mal wieder wenig Sinn, aber damit will ich es jetzt versuchen.

    Ich habe jetzt folgenden Code, der mir ein DGV füllt und mithilfe von ComboBox-Auswahl die BindingSource dazu filtert (bisher alles das Start-Form):

    VB.NET-Quellcode

    1. Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
    2. tblBindingSource.Filter = "bla = ComboBox2.SelectedItem.ToString"
    3. End Sub


    Jetzt versuche ich ein zweites Form zu bauen auf dem gefiltert wird. Aber da krieg ich keine Daten mehr.

    VB.NET-Quellcode

    1. Private frmFilter1 as frmFilter
    2. Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
    3. frmFilter1 = New frmFilter
    4. frmFilter1.tblBindingSource.Filter = "bla = ComboBox2.SelectedItem.ToString"
    5. frmFilter1.Show
    6. End Sub


    Viele Grüße
    Du musst natürlich Deine Daten auch ans andere Form weitergeben. Wo stecken denn Deine Daten drin? tDS? nur-DB? eigener DataContainer? DGV zählt nicht als Antwort! :P
    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.
    Das ist aber nur die halbe Miete.
    Wenn Du eine Stringvariable mit "Test" befüllst und dann noch ne 2. Stringvariable anlegst, ist die 2. ja auch leer und es steht nicht "Test" drin.
    Such mal im Forum nach formübergreifenden DataBinding.
    EdR macht es so, dass er das tDS übergibt, dieses in die DS1-Variable von Form2 steckt und dann alle BindingSources auf diese neue Instanz umstöpselt.
    Ich bin eher Fan von: eine Zusatz-BS anlegen, die auf die Form-eigene-tDS-Instanz verweist, alle anderen BSs verweisen auf die tDS-BS und dann muss nach Übergabe des tDS an Form2 nur diese tDS-BS umgestöpselt werden.
    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.
    Achso das DS1 auf Form2 ist eine leere Instanz, weil Form2 die nicht gefüllt hat...
    Aber warum bleibt die Form2.BS leer, wenn ich Form2.DS1 = Form1.DS1 setze?

    Wenn ich die Form1 BS auf eine Form2 BS kopiere, dann ändern sich beide gleich, weil das nur verschiedene Zeiger auf dieselbe Datenstruktur sind. Also BS2.Filter filtert auch BS1.
    Hab auch noch nicht ganz verstanden, was ihr mit "umstöpseln" meint.

    Haudruferzappeltnoch schrieb:

    Aber warum bleibt die Form2.BS leer, wenn ich Form2.DS1 = Form1.DS1 setze?
    Den Denkfehler hatte ich auch mal vor ein paar Jahren: Weil das die BindingSources nicht interessiert. Die sind immer noch ans leere Ursprungs-tDS gekoppelt. Da steht in der Form2.Designer.VB nämlich drin BindingSource1.DataSource = DS1
    Das wär fast so, als ob Du schreibst:

    VB.NET-Quellcode

    1. Dim x = 1
    2. Dim y = x
    3. x = 2
    und dann erwartest, dass y auch 2 ist. Was natürlich nicht so ist.
    Du sollst auch keine BS kopieren.
    Umstöpseln heißt: BS.DataSource neu setzen.
    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.
    Also im Form2 Designer ist Me = Form1? Weil DS1 existiert ja auch auf Form2 (Und Me. davor schreiben ist wie nichts davor schreiben)

    Aber ja so gehts dann:

    VB.NET-Quellcode

    1. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
    2. DS1 = Form1.DS1
    3. BindingSource1.DataSource = DS1 ' steht genauso im Designer.vb Me.BindingSource1.DataSource = Me.DS1 und Me zeigt hier Form2 beim Hovern
    4. End Sub

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

    Haudruferzappeltnoch schrieb:

    Also im Form2 Designer ist Me = Form1?
    Nee, wie kommste denn da drauf? Hab ich sowas angedeutet? Dann sollte ich das nächste Mal präzisiser werden.

    Gut, wenn das klappt, kannst Du es so lassen. Aber halt, Kommando Zurück! Zeile#2 ist tabu!
    Mach das mit einer Methode, die das tDS weitergibt. Solche Späßchen à la DS1 = Form1.DS1 haben nix in sauberem Code verloren. Also:

    VB.NET-Quellcode

    1. Private frmFilter1 as frmFilter
    2. Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
    3. frmFilter1 = New frmFilter
    4. frmFilter1.SetData(DS1)
    5. frmFilter1.tblBindingSource.Filter = "bla = ComboBox2.SelectedItem.ToString"
    6. frmFilter1.Show()
    7. End Sub
    8. 'und in frmFilter:
    9. Friend Sub SetData(tDS As DeinDataSet)
    10. DS1 = tDS
    11. End Sub


    Wenn Du nur eine oder 2 BSs hast, ist das soweit ok. Wenn es viele werden, dann wird's aufwendiger, dann kannste Dir nochmal mein tDS-BS-Vorschlag durch den Kopf gehen lassen - falls Du denn genau weißt, was ich meine. Ansonsten lad ich mal n Beispiel hoch.
    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.
    Also ich probier es morgen nochmal.

    Was ich nur meine ist in Form1.Designer.VB steht ja genauso Me.tblBindingSource.DataSource = Me.DS1
    wie es auch in Form2.Designer.VB steht. In Form1 bekommt DS1 einen DataAdapter.Fill, in Form2 wird es durch Neuzuweisung angepasst.
    Wo da jetzt der Unterschied ist, dass die BS einmal mitzieht und einmal nicht, das erfasse ich noch nicht.
    In Form1 wird der BS als DataSource das Form1-DS1 zugewiesen. Anfangs ist DS1 leer und die BS kennt somit keine Inhalte. Ist ja in DS1 noch nix drin. Dann wird DS1 befüllt. Damit hat die BS nun Zugriff auf die tDS-Daten.
    Nun Form2:
    In Form2 wird der BS als DataSource das Form2-DS1 zugewiesen. Anfangs ist DS1 leer und die BS kennt somit keine Inhalte. Ist ja in DS1 noch nix drin. Aber das ändert sich ja auch nicht. Sobald die Zuweisung DS1 = Form1.DS1 kommt, wird ja der Form2.DS1-Inhalt nicht geändert wie beim DataAdapter.Fill in Form1. Würdest Du also für das Form2.DS1 ebenfalls DataAdapter.Fill aufrufen, würde sich der Form2.DS1-Inhalt ändern und die BS wüsste bescheid. Das passiert aber nicht. Stattdessen wird Form2-DS1 durch das Form1.DS1 ersetzt. Das ist aber für die BS irrelevant. Stell es Dir vielleicht so vor:
    Du bekommst einen Lottogewinnbrief mit gelbem Papier, der liegt auf Deinem Schreibtisch (Form2.BS-DataSource wird auf Form2.DS1 in der Designer.vb festgelegt). Nun kommt jemand daher und legt einen komplett anderen Brief mit rotem Papier auf Deinen Schreibtisch und packt den gelben Brief in die Küche (Form2.DS1 = Form1.DS1) -> der gelbe Brief ist noch da, aber nicht mehr, wo er zuerst war. Macht aber nix, weil Dir nicht der Ablageplatz wichtig ist, sondern die Tatsache, dass der Brief aus gelbem Papier ist. Und nun weißt Du, dass der rote Brief nicht Deiner ist, Du findest den gelben Brief in der Küche, den roten ignorierst Du (eben weil Du weißt, dass es nicht Deiner ist) und Du kümmerst Dich weiter um den gelben -> Form2.BS-DataSource ist immer noch der Inhalt der ehemals leeren Form2-DS1-Variable.

    ##########

    Codebeispiel:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Box As New Container
    4. Dim NewForm = New Form
    5. Box.Content = NewForm
    6. NewForm = Nothing 'Box.Content bleibt weiterhin ein neues Form. Es ist nur nicht mehr über NewForm erreichbar.
    7. End Sub
    8. End Class
    9. Friend Class Container
    10. Property Content As Object
    11. End Class

    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“ ()

    Ok ich habs jetz wie folgt versucht:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private f1 As String
    3. Private f2 As String
    4. Private frmFilter As Form2
    5. Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
    6. If frmFilter Is Nothing Then 'Nur eine Instanz
    7. frmFilter = New Form2(DS1)
    8. End If
    9. frmFilter.Show()
    10. End Sub
    11. Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
    12. Dim hold = ComboBox2.SelectedItem.ToString
    13. Dim split = hold.IndexOf("/"c)
    14. f1 = hold.Substring(0, split)
    15. f2 = hold.Substring(split + 1, hold.Length - 1 - split)
    16. frmFilter.SetFilter(f1, f2)
    17. End Sub
    18. End Class
    19. Public Class Form2
    20. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
    21. TblBindingSource.DataSource = DS1
    22. End Sub
    23. Friend Sub New(tDS As DataSet1)
    24. InitializeComponent()
    25. DS1 = tDS
    26. End Sub
    27. Friend Sub SetFilter(f1 As String, f2 As String)
    28. TblBindingSource.Filter = $"bla = {f1} AND bla2 = {f2}"
    29. End Sub
    30. End Class


    Jetzt gibts da noch ein kleines Problem mit der Form2 Instanz. Wenn ich die schließe dann kann ich sie nicht erneut Aufrufen, weil die im Disposed Status ist, aber auch nicht Nothing.

    Wie ist das am besten zu lösen? Neu erzeugen? Eigentlich kann es immer dieselbe Instanz bleiben, denn es gibt nur eine Bindingsource für den Filter. Es sollen also auch keine mehreren Form2 aufgerufen werden können.
    Oder kann ich die Instanz schließen mit der Möglichkeit sie erneut aufzurufen? Wahrscheinlich ein Trick im Closing-Event der Form2? (Nebenbei bemerkt Form1 zeigt immer die ungefilterte Tabelle, wahrscheinlich sollten die ComboBoxen noch auf Form2 zum Filtern, aber lassen wir das erstmal so)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Arbeite sauber mit Dialogen:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Using frmFilter1 As New frmFilter
    3. frmFilter1.SetData(DS1)
    4. frmFilter1.tblBindingSource.Filter = "bla = ComboBox2.SelectedItem.ToString"
    5. frmFilter1.ShowDialog(Me)
    6. End Using
    7. End Sub

    Danach ist von frmFilter1 nix mehr da und Du kannst den Code problemlos wieder neu aufrufen.
    Wenn Dialoge nicht infrage kommen, dann eben einfach frmFilter1 = New frmFilter
    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.
    Korrekt. Es kann immer nur einen Dialog geben. Der dann aber selber wieder einen Dialog erzeugt. Aber es können nicht 2 gleiche Dialoge gleichzeitig auftauchen. Naja, vielleicht irgendwie schon. Aber der Sinn eines Dialogs ist, eine Information zu besorgen und das restliche Programm erstmal anzuhalten, bis die Information vorliegt

    Kleiner Hinweis nebenbei: Events im Hauptform können trotzdem noch auftreten.
    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.