Nebelkerzenverfolgung: irreführende Fehlermeldung bei Dialogform-tDS-DGV-ComboBoxColumn-Konstellation [gelöst]

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

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

    Nebelkerzenverfolgung: irreführende Fehlermeldung bei Dialogform-tDS-DGV-ComboBoxColumn-Konstellation [gelöst]

    Hallo zusammen,

    ich kam bisher sehr gut mit tDS, DGVs und Co zurecht. Nun habe ich folgendes Problem inkl. Workaround, welche ich nicht nachvollziehen kann.
    In meinem tDS habe ich 4 Tabellen: T1 (Items), T2 (ProcessControlParametersX) und als Hilfstabelle T3 (ProcessControls), die die beiden miteinander verknüpft, so wie die Article-Tabelle im VVV-Tutorial vom EdR. Zusätzlich eine T4 (Vessels).

    In einer ComboBox eines Subforms werden die T4-Einträge aufgelistet, in einem DGV lasse ich mir T3 anzeigen. Eine DGV-Spalte ist eine ComboBox-Spalte, die mir die konkreten Werte von T2 anzeigt, indem ich DataSource, ValueMember und DisplayMember einstelle. Wenn ich nun zur Laufzeit das Subform instanziiere, das tDS zu Fuß umstöpsle und das Subform als Dialog zeigen lassen will, erhalte ich eine Ex, dass eine in T3 definitiv vorhandene Spalte nicht Teil der Tabelle sei.

    Der Code dazu:

    VB.NET-Quellcode

    1. Using Dlg As New FrmControls
    2. Dlg.Tds = Tds
    3. Dlg.BsItems.DataSource = Tds
    4. Dlg.BsVessels.DataSource = Tds
    5. Dlg.BsProcessControlParameters.DataSource = Tds
    6. Dlg.ShowDialog(Me)
    7. End Using

    Habe erkannt, dass es mit BindingSource.Suspend&ResumeLayout behebbar ist:

    VB.NET-Quellcode

    1. Using Dlg As New FrmControls
    2. Dlg.BsItems.SuspendBinding()
    3. Dlg.BsProcessControlParameters.SuspendBinding()
    4. Dlg.BsProcessControls.SuspendBinding()
    5. Dlg.BsVessels.SuspendBinding()
    6. Dlg.Tds = Tds
    7. Dlg.BsItems.DataSource = Tds
    8. Dlg.BsVessels.DataSource = Tds
    9. Dlg.BsProcessControlParameters.DataSource = Tds
    10. Dlg.BsVessels.ResumeBinding()
    11. Dlg.BsProcessControls.ResumeBinding()
    12. Dlg.BsProcessControlParameters.ResumeBinding()
    13. Dlg.BsItems.ResumeBinding()
    14. Dlg.ShowDialog(Me)
    15. End Using


    Nun zum eigentlichen Problem: Entferne ich das Binding der ComboBox zu T4, dann läuft das Programm, obwohl mir vorher ein Problem mit T3 bescheinigt wird. Das kann's ja wohl nicht sein! Woher rührt dieses merkwürdige Verhalten? Und warum kommt da solch eine irreführende Meldung bzgl der fehlenden Spalte Name? Der Debugger bestätigt mir die Existenz der Tabellenspalte. Was noch dazukommt: Lasse ich Suspend- und ResumeBinding weg und setze die Zeile Dlg.BsProcessControls.DataSource = Tds.ProcessControls vor die ShowDialog-Zeile, klappt auch alles. Ich habe das Gefühl, dass ich die wahre Ursache des Problems noch nicht erfasst habe. Wer kann mir weiterhelfen?




    Lösung in Post#5
    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:

    Spalte Name?
    könnte auch ev.mit dem reservierten Wort Name zu tun haben - benenne deine Spalte einmal um...
    Ich glaube, so etwas Ähnliches hattest du schon einmal...
    ärgerlicher Nebeneffekt bei bestimmter DataColumns-Namensgebung

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

    anbei

    @VB1963: Tja, das war damals eine von mir selbst entzündete Nebelkerze. Die Spalte [Name] war nur ein roter Hering, die aber komplett unschuldig war. Ich hatte damals nur falsch geschlussfolgert und übersehen, dass implizit ein einfaches DataBinding erstellt wurde, als ich ne ComboBox aus den Datenquellen rausgezogen hatte. Diesen Fehler hab ich seitdem nicht mehr begangen. Kein simples DataBinding in jener T4-gebundenen ComboBox.
    Allerdings habe ich es natürlich trotzdem getestet. Name wurde in T3 zu Name2 und in der Vessel-DataTable zu Name1. Dann wird angemeckert, dass Name2 nicht Teil von T3 wäre.
    Dateien
    • Testprogramm.zip

      (49,04 kB, 79 mal heruntergeladen, zuletzt: )
    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.
    Es hängt glaub iwie mit dem Zwischenzustand zusammen, der entsteht, wenn die Datasource der ComboColumn schon aufs neue tDs verwiesen ist, während das DGV, wo die Column drinne ist, noch aufs alte verweist (oder umgekehrt oderso).
    Oder evtl. auch mit einer unglücklichen Reihenfolge der Initialisierung der BindingSources im DesignerCode.
    Dadurch werden beim Umstöpseln Events in unglücklicher Reihenfolge gefeuert, und das Ergebnis ist ein kleines Unglück.
    Richtig nachweisen kann ich das grad nicht.

    Aber Ich hab folgenden Workaround mir ausgedacht:

    VB.NET-Quellcode

    1. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    2. Using Dlg As New FrmControls
    3. Dim isupps = {Dlg.BsProcessControls, Dlg.BsItems, Dlg.BsVessels, Dlg.BsProcessControlParameters}.Cast(Of ISupportInitialize)().ToList
    4. isupps.ForEach(Sub(isupp) isupp.BeginInit())
    5. Dlg.Tds = Tds
    6. Dlg.BsItems.DataSource = Tds
    7. Dlg.BsVessels.DataSource = Tds
    8. Dlg.BsProcessControlParameters.DataSource = Tds
    9. isupps.ForEach(Sub(isupp) isupp.EndInit())
    10. Dlg.ShowDialog(Me)
    11. End Using
    12. End Sub

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

    Es ist wie bei einem anderen Thread von mir. Ich weiß zwar wieder nicht, warum es klappt, aber es funktioniert für den Moment. Mal sehen, wieviele solcher Überraschungen ich noch so erleben werde :cursing:
    Die Meldungen und das beschriebene Verhalten sind aber immer noch verwirrend.
    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“ ()

    ich weisses auch nicht genau, aber ungefähr:
    BindingSources sind miteinander und mit DGVs verknüpft - mit DGV manchmal sogar doppelt: 1) als DataSource, 2) als Datasource einer DgbComboboxColumn.
    Der Kram kommuniziert intern über allerlei Events mitnander und hin und her und rauf und runter: wenn eine Datasource sich ändert, wenn eine Position, sei es im Control oder inne BS, oder wenn Daten zukommen/entfernt/geändert wern.
    Also äusserst komplex, und hängt alles am selben tDS.

    Jo, und Umstöpseln kann immer nur eine Bs nach der anneren sich vornehmen, und da ist ja logisch, dasses da ungültige Zwischenzustände gibt, und solange die BindingSources so munter miteinander schwätzen über jeden Pups knallt das natürlich wenn da auf einmal eine zwischen ist, die an einem anneren Dts (baugleich, aber anneres Objekt) hängt.

    Meine Lösung ist aussm DesignerCode abgeschrieben: .BeginInit() ist ein Pattern, der das Objekt anweist, erstmal Füsse still zu halten, und zwar bis .EndInit kommt.
    Dassis extra dafür da, um komplexe Initialisierungen durchführen zu können, an denen mehrere Objekte beteiligt sind und voneinander abhängig.
    Klingt nachvollziehbar. Jetzt stellt sich für mich abschließend die Frage, ob Du das in Deinen tDS-/DB-Extensions so schon eingebaut hattest oder einen komplett anderen Weg da gehst. Denn es klingt ein wenig so, als ob dieses funktionierende Workaround (oder ist es nicht vielleicht doch eine Lösung?) jetzt erst entstanden wäre.
    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.