BindingSource Probleme

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

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    BindingSource Probleme

    Hallo,

    ich habe ein Hauptform das überwiegend in einem DataSet Werte ändert.
    Ich möchte ein zweites Form auch auf das DataSet zugreifen lassen, um Dinge anzeigen und Werte ändern können. Das zweite Form wird als Dialog des Hauptforms aufgerufen. Es passiert also nicht gleichzeitig
    Trotzdem muss ich aber ja dieselbe Instanz des DataSets verwenden, damit beide Forms immer dieselben Daten behalten, richtig?
    Wenn ich dem zweiten Form diese Instanz zuschuster, dann muss ich die Bindingsource für die DGVs aber händisch an diese Instanz anknüpfen, und das klappt nicht wirklich. Das DGV bleibt einfach leer

    VB.NET-Quellcode

    1. Friend Class Form2
    2. Friend Sub New(DS As DataSet1)
    3. InitializeComponent()
    4. TestBindingSource.DataSource = DS
    5. TestBindingSource.DataMember = "Test"
    6. End Sub
    7. End Class

    dgvTest.DataSource ist dabei TestBindingSource über den Designer festgelegt.
    ResetBindings oder SuspendBinding ändert daran auch nichts. Ich weiß grad nicht worans liegt, wenn ich im Hauptform-Designer schaue, steht da auch nicht viel mehr.

    Aufruf falls relevant

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Using frm2 As New Form2(DS1)
    3. frm2.ShowDialog(Me)
    4. End Using
    5. End Sub


    Viele Grüße

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

    Du könntest in der ersten Form eine Public Property des Datasets anlegen auf die dann beide Forms zugreifen, oder gleich eine DataSet-Klasse schreiben auf die dann beide Forms zugreifen!

    z.B.: Dataset global im Programm verfügbar machen

    oder: learn.microsoft.com/de-de/visu…?view=vs-2022&tabs=csharp

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

    Ich kann's nicht nachvollziehen. Bei mir klappt's, siehe Anhang
    btw: Wenn später mehrere BindingSources auf den Forms verteilt sind und Du es manuell umdrahten willst, müsstest Du die DataSource aller BindingSources anfassen. Du kannst es aber auch einfacher machen, indem Du Dir eine BindingSource auf's Form packst, welche als DataSource das tDS hat (im weiteren tDS-BindingSource). Alle anderen BindingSources können dann als DataSource nicht das SubForm-tDS, sondern diese tDS-BindingSource haben. Wenn Du dann bei Dialogerstellung nur die DataSource der tDS-BindingSource neu setzt, sind alle anderen BindingSources gleich korrekt eingestellt.
    Bilder
    • Pic1.png

      27,75 kB, 1.017×261, 59 mal angesehen
    • Pic2.png

      23,93 kB, 1.027×295, 54 mal angesehen
    Dateien
    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.
    Wieso, @VaporiZed nimmt ja auch die Instanz aus der Hauptform

    Aufruf der Subform mit Übergabe der Tds:

    VB.NET-Quellcode

    1. Using Dialog As New Form1(Tds) 'Instanz wird an Subform übergeben
    2. Dialog.ShowDialog(Me)
    3. End Using


    Übernahme und neu setzen der Tds:

    VB.NET-Quellcode

    1. Public Sub New(Tds As Tds)
    2. InitializeComponent()
    3. BsBooks.DataSource = Tds 'Hier wird die übergebene Tds-Instanz drangeklöppelt
    4. End Sub
    Genau. Die tDS-Instanz auf dem SubForm ist eine eigene. Würde ich den abgewandelten Konstruktor nicht haben, würde das DGV im SubForm leer bleiben, weil das SubForm-tDS leer ist, da die Daten ja nur in der MainForm-tDS-Instanz drinstecken. Das SubForm-tDS dient hier nur als Designerhilfe, damit man über die BS im DGV schon mal die Datenspalten der DataTable konfigurieren kann. Du kannst alternativ auf die tDS-Instanz weglassen und in der SubForm.Designer.vb bei der BS hinschreiben: BS.DataSource = GetType(DieAnzuzeigendeDataTable), damit das DGV weiß, was später drinstehen wird.

    Ah, kann es sein, dass Dein SubForm-DGV deswegen leer ist, weil Dir dieser Datentypbezug fehlt? Denn wenn Du erst zur Laufzeit festlegst, was die SubForm-BS als DataSource und DataMember hat, werden DGV-Spalten zur Laufzeit nicht automatisch erzeugt. Das geht nur, wenn beide BS-Properties zur Designzeit festgelegt werden. Und dafür wird die zusätzliche, aber leere tDS-Instanz auf dem SubForm verwendet.
    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“ ()

    Tds = Tds? Wahrscheinlich eher Me.Tds = Tds, sonst wär's Murks ;)
    Und mit der Benennung …, naja. Wär für mich akzeptabel. Aber ja, man sollte die Zuweisung von MainForm-tDS auf SubForm-tDS schon deshalb machen, weil man ja sonst nur mühselig im Code auf das eigentliche tDS zugreifen kann.
    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.
    Kann man schon. Es ist aber umständlich, alle DGV-Columns selber anzulegen, siehe SubForm.Designer.vb:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. '
    2. 'BooksDataGridView
    3. '
    4. Me.BooksDataGridView.AutoGenerateColumns = False
    5. Me.BooksDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
    6. Me.BooksDataGridView.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.IDDataGridViewTextBoxColumn, Me.TitleDataGridViewTextBoxColumn, Me.ISBNDataGridViewTextBoxColumn})
    7. Me.BooksDataGridView.DataSource = Me.BsBooks
    8. Me.BooksDataGridView.Location = New System.Drawing.Point(28, 26)
    9. Me.BooksDataGridView.Name = "BooksDataGridView"
    10. Me.BooksDataGridView.Size = New System.Drawing.Size(391, 220)
    11. Me.BooksDataGridView.TabIndex = 0
    12. '
    13. 'IDDataGridViewTextBoxColumn
    14. '
    15. Me.IDDataGridViewTextBoxColumn.DataPropertyName = "ID"
    16. Me.IDDataGridViewTextBoxColumn.HeaderText = "ID"
    17. Me.IDDataGridViewTextBoxColumn.Name = "IDDataGridViewTextBoxColumn"
    18. '
    19. 'TitleDataGridViewTextBoxColumn
    20. '
    21. Me.TitleDataGridViewTextBoxColumn.DataPropertyName = "Title"
    22. Me.TitleDataGridViewTextBoxColumn.HeaderText = "Title"
    23. Me.TitleDataGridViewTextBoxColumn.Name = "TitleDataGridViewTextBoxColumn"
    24. '
    25. 'ISBNDataGridViewTextBoxColumn
    26. '
    27. Me.ISBNDataGridViewTextBoxColumn.DataPropertyName = "ISBN"
    28. Me.ISBNDataGridViewTextBoxColumn.HeaderText = "ISBN"
    29. Me.ISBNDataGridViewTextBoxColumn.Name = "ISBNDataGridViewTextBoxColumn"


    Oder Du setzt die DGV-AutoGenerateColumns-Property auf True und schreibst

    VB.NET-Quellcode

    1. Public Sub New(Tds As Tds)
    2. InitializeComponent()
    3. BsBooks.DataSource = Tds
    4. BsBooks.DataMember = "Books"
    5. BooksDataGridView.DataSource = BsBooks
    6. End Sub

    Nur wozu? Sollen denn verschiedene DataTables abgebildet werden oder wozu willst Du Dich zur Designzeit noch nicht festlegen?
    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“ ()

    VaporiZed schrieb:

    Tds = Tds? Wahrscheinlich eher Me.Tds = Tds, sonst wär's Murks ;)


    Sorry ich schreibe nur hier fürs Forum ab und zu mal etwas VB Code, eigentlich verwende ich ausschliesslich C# und selbst dort würde ich das Equivalent this nicht verwenden aber einen anderen Namen für die Transfervariablen.
    Ne ok, das passt schon. Ist nur zum Verständnis.

    Ich habe auch noch ein anderes Phänomen, also ich ersetze nun die leere DS1 Instanz. Wenn ich es so mache:

    VB.NET-Quellcode

    1. Friend Sub New(DS As DataSet1)
    2. InitializeComponent()
    3. Me.DS1 = DS
    4. TestBindingSource.DataSource = DS1
    5. End Sub

    Dann verliert mein Dgv seine eingestellten Column.Width. Ich hab in der Sub New am Ende geschaut: In dem Moment sind die Werte alle noch da. Deshalb hab ich das Ganze nach vorne verlagert:

    VB.NET-Quellcode

    1. Friend Sub New(DS As DataSet1)
    2. InitializeComponent()
    3. Me.DS1 = DS
    4. End Sub
    5. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
    6. TestBindingSource.DataSource = DS1
    7. End Sub
    So bleiben die eingestellten Werte erhalten. Also zwischen New und Load scheint irgendwas im DGV zu resetten, wenn im New die DataSource der BindingSource geändert wird.
    Es muss irgendwas mit dem Laden des DGVs zutun haben, das muss schon geladen sein bevor, die DataSource geändert wird.

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

    Im New-Ereignis ist das DGV noch nicht initialisiert, ich denke es hängt damit zusammen.
    Ich würde dennoch niemals das Form_Load Event nutzen, immer das Form_Shown. Das Form_Load Event verhält sich ungünstig wenn es doch mal einen Fehler geben sollte und verschluckt Fehler ohne sie anzuzeigen.
    Aber das nur am Rande, sollte auch hinreichend bekannt sein.

    Dksksm schrieb:

    sollte auch hinreichend bekannt sein
    Was ich gerne nochmal evaluieren lassen würde. Ich weiß, dass es zahlreiche Berichte gibt. Aber bei mir bekomme ich dieses Fehlverhalten (auf Anhieb) nicht mehr zu spüren.

    Haudruferzappeltnoch schrieb:

    Dann verliert mein Dgv seine eingestellten Column.Width
    Ich habe es testweise mit AllCells und Fill eingestellt, aber das von Dir beschriebene Verhalten zeigt sich mir nicht.

    VB.NET-Quellcode

    1. Public Sub New(Tds As Tds)
    2. InitializeComponent()
    3. Me.Tds = Tds
    4. BsBooks.DataSource = Tds
    5. End Sub

    Auch nicht mit NotSet und irgendwelchen Spaltenbreiten
    Bilder
    • Result.png

      39,63 kB, 1.132×446, 52 mal angesehen
    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.
    Ich habe im Designer in der dgv.Columns Eigenschaft Width Werte für die einzelnen Spalten vergeben, Default ist 100. Im New kann ich am Ende an genau dieser Stelle dann zum Beispiel auch immer noch 70 auslesen. Aber dann wird trotzdem 100 angezeigt. Ich probiere deine Einstellungen auch gerne nochmal heute Abend. Ich denke mal die Fill Methode läuft dauernd, weil das ja auch bei Resize oder so passen muss.