bei Formularen mit Child->Parent Beziehung werden gebundene Felder der Parenttabelle nicht geleert wenn in selbiger kein passender Datensatz vorhanden ist

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

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

    bei Formularen mit Child->Parent Beziehung werden gebundene Felder der Parenttabelle nicht geleert wenn in selbiger kein passender Datensatz vorhanden ist

    Ich habe ein Formular mit Details, z.B. Rechner, denen ich erst die übergeordneten Angaben z.B. Rechnermodell bei der Erfassung zuordnen möchte.
    Beide Bindingsourcen befinden sich mit ihren gebundenen Feldern in einem Formular.
    Die beiden Bindingsource sind über eine Combobox cboRechnermodell miteinander verbunden

    VB.NET-Quellcode

    1. cboRechnermodell.Datasource=bsRechnermodell
    2. cboRechnermodell.Displaymember="Rechnermodell"
    3. cboRechnermodell.Valuemember="ID_Rechnermodell"

    Über die Eigenschaften ist cbo_Rechnermodell.SelectedtValue an bsRechner.ID_Rechnermodell gebunden.

    Solange zur Childrow eine Parentrow existiert arbeitet das Formular sauber, ist die Parentrow allerdings noch nicht gesetzt, bleiben in den gebundenen Textfeldern die vorigen Werte erhalten.
    Wie kann ich das Problem lösen ?

    Chid=tbl_Rechner mit den Feldern ID_Rechner,ID_Rechnermodell,Rechnername,Seriennr....
    Parent=tbl_Rechnermodell mit den Feldern ID_Rechnermodell, Hersteller, Rechnermodell, Prozessor, RAM...
    Eh ... what? Ich blick's nicht. Geht die Problembeschreibung leichter?
    Dann eben Spekulatius: Was hast Du über den ComboBox.SelectedValue gebunden? BsRechner.ID_Rechnermodell, ok. Was hat BsRechner als Datengrundlage? Wenn es natürlich nur die Rechner-DataTable ist, dann wird das nix. Du musst daran jene Rechnerzeilen binden, die mit dem aktuellen Rechnermodell verknüpft sind. Dazu musst Du als Bs-Datenquelle folgendes nehmen: bsRechnermodell und als DataMember die Verknüpfung zwischen den DataTables. Bei mir wär das (siehe tDS-Screenshot, der Deiner Problembeschreibung ggf. fehlt) FK_Rechnermodelle_Rechner
    Bilder
    • TdsScreenShot.png

      3,77 kB, 180×235, 108 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.
    Im Bild ist hoffentlich besser zu erkennen was ich will.
    Anhand der Combobox Rechnermodell, sollen die technischen Angaben zum Rechnermodell mit angezeigt werden.
    Wenn der Rechner erfaßt wird, ist das Rechnermodell ja noch nicht zugeordnet, trotzdem stehen dort die Daten des zuletzt angezeigten Datensatzes drin.
    Genau das stört mich.

    Ist das Modell sauber zugeordnet, werden auch die richtigen Daten angezeigt.

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

    Wieder stellt sich die Frage: Die ganzen Details, die unten zu sehen sind, sind nicht immer aktuell, habe ich das richtig verstanden? Ach wurscht. Zeig doch mal bitte für ein CE, welches nichtaktuelle Daten zeigt, das Eigenschaftenfenster der BindingSource. Also sowas:


    bzw: Dein Screenshot ist ... suboptimal. 70% weiß. Und oben klein die Infos :|
    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.

    wenn Rechnermodell zugeordnet ist funktioniert es, wenn nicht bleiben die letzten Eintragungen erhalten

    Wenn das Rechnermodell richtig zugeordnet ist funktioniert das Programm wie es soll, es werden die richtigen Daten angezeigt.
    Ist das Rechnermodell nicht zugeordnet, also ID_Rechnermodell=DBNull werden die Inhalte der an die tbl_Rechnermodell gebundenen Daten nicht geleert, sondern zeigen die Werte des letzten aufgerufenen Datensatzes an.

    Ich möchte aber auch die tbl_Rechner als führende Tabelle haben, da ich beim Erfassen das Modell erst zuordnen muß.
    Also ich rufe den Rechner auf und weise ihm ein Modell zu.
    Wenn das Modell zugeordnet ist, werden die Daten aus der Tabelle Rechnermodell angezeigt.


    Mist, ich dachte, dass ich es nun begreifen würde, aber doch nicht. (Ich schätze mal, dass Du keine Solution hochladen kannst, oder?)
    Also nochemal. Zum Ablauf, damit ich das mal kapiere:
    Du hast Rechnermodell-Tabellenzeilen. Und Rechner-Tabellenzeilen.
    Du wählst eine Rechner-Zeile aus und ordnest dann das Rechnermodell zu.
    Und wenn Du jetzt einen neuen Rechner auswählst, bleiben die alten Rechnermodelldaten stehen.

    Hm, kann ich nicht nachstellen.
    Wie ist es denn mit der Rechnermodellcombobox, wenn ein neuer Rechner ohne Zuordnung ausgewählt wird? Ist die Box leer? Wenn nein, ist das Binding falsch, wenn ja, aber die Details bleiben, dann ist deren Binding falsch.
    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.

    Schoofi schrieb:

    Ist das Rechnermodell nicht zugeordnet, also ID_Rechnermodell=DBNull werden die Inhalte der an die tbl_Rechnermodell gebundenen Daten nicht geleert, sondern zeigen die Werte des letzten aufgerufenen Datensatzes an.
    Das sollte eiglich garnicht funktionieren, dass ID_Rechnermodell=DBNull.
    Daher vermute ich, dass da iwo ein TryCatch beteiligt ist, der die Fehlermeldung verschluckt.
    Hüh? Wieso sollte das nicht funktionieren? Man kann doch in jener Spalte bei NullValue statt (ThrowException) eine 0 eintragen. Ok, beim Schreiben ist mir klar geworden, dass bei NullValue für einen Int32-Wert weder <DBNull>* noch (Nichts) oder (Empty) eingetragen werden kann.

    *interessanterweise durfte ich feststellen, dass man zwar in die Spalte <DbNull> eintragen kann, aber damit auch nicht weit kommt, da dann die Designer.vb des tDS ersatzlos gelöscht wird, da sie nun nicht mehr neu geschrieben werden kann. Es kommt nämlich folgende Fehlermeldung:
    Fehler in benutzerdefiniertem Tool: Es konnte kein Code generiert werden. Es konnte kein Code generiert werden. Ein Aufrufziel hat einen Ausnahmefehler verursacht. Die Eingabezeichenfolge hat das falsche Format. Ein Aufrufziel hat einen Ausnahmefehler verursacht. Die Eingabezeichenfolge hat das falsche Format.
    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.
    Ups ich meinte natürlich NULLValue, ich dachte das wäre das gleiche wie dbNull.
    Ansonsten bin ich momentan nicht ganz so schnell mit testen, da ich vorhin auf Office 365 umgestellt wurde und erstmal die Verweise wieder gerade biegen muß.
    Ich hoffe mal das die Anwendungen auf den noch nicht umgestellten Rechnern dann trotzdem laufen.
    Danach mache ich mal eine kleine Testsolution zu dem Thema. Das Original ist dafür zu groß, ca 30 Tabellen und entsprechend viel Formulare und Klassen.
    Ok, die Detail-CEs sind direkt an die DataTable gebunden, die ComboBox nur indirekt. Wenn jetzt also Rechner3 ausgewählt wird, erhält die ComboBox als SelectedItem den Wert Nothing. Die RechnermodellBindingSource verbleibt jedoch auf der zuletzt gewählten Position - und zeigt somit die "alten" Werte an. Ob das Problem jetzt durch geschicktes DataBinding behebbar ist? Keine Ahnung. Zumindest ist das Problem mal klar.
    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.
    am Datenmodell unstimmig ist, dass tbl_Rechner.ID_Rechnermodell nullwerte erlaubt.
    Inner Realität gibt es keine Rechner ohne Rechnermodell, also darfs das auch im Modell nicht geben.
    Was es hingegen gibt sind Rechner, deren Rechnermodell unbekannt ist.
    Also lege einen "unbekannt"-Datensatz im tbl_Rechnermodell an, und benutze ihn.
    Danke, aber schade das es nicht anders geht. Das war nur ein Beispiel wo ich das Verfahren auf die Art anwende. Unter ACCESS hatte ich damit nie Probleme.
    Es gibt tatsächlich in anderen Tabellenrelationen tatsächlich Fälle wo nicht zwingend eine Parentrow existiert.
    Da werde ich dann wohl den von EDR empfohlenen Workarround einsetzen müssen.
    Es gibt ne Möglichkeit: Nutze statt TextBoxen für Prozessor, RAM, etc. ComboBoxen, stelle sie so ein, wie die Rechnermodell-ComboBox, nur, dass sie eben auf eine andere Spalte zeigen (RAM statt Name etc.) und zum Schluss den DropDownStyle von DropDown auf Simple. Ggf. noch deaktivieren, wenn Du die Daten des Rechnermodells im Hauptformular nicht ändern willst. Sieht zwar nicht sooo Bombe aus, aber ggf. reicht es Dir.
    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 jetzt noch eine andere Lösung gefunden, viele Wege führen nach Rom.
    Es sieht so aus, als ob

    VB.NET-Quellcode

    1. Bindingsource.current
    nur dann auf nothing zeigt wenn die Bindingsource keine Listeneinträge aufweist, ansonsten scheint sie mindestens auf einer Datarow zu stehen.
    Folglich habe ich eine zweite Bindingsource zur Anzeige eingebaut und setze dort den

    VB.NET-Quellcode

    1. Bindingsource.Filter= "False"
    , wenn

    VB.NET-Quellcode

    1. Combobox.selectedindex=-1


    VB.NET-Quellcode

    1. Private Sub cboRechnermodell_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboRechnermodell.SelectedIndexChanged
    2. If Me.cboRechnermodell.SelectedIndex = -1 Then
    3. Me.bsRechnermodell.Filter = "False"
    4. Else
    5. Me.bsRechnermodell.RemoveFilter()
    6. Me.bsRechnermodell.Position = Me.bsRechnermodell.Find(DsRechnerliste.tbl_Rechnermodell.ID_RechnermodellColumn.ColumnName, CInt(Me.cboRechnermodell.SelectedValue))
    7. End If
    8. end sub