DataGridView und TextBoxen an BindingSource gebunden - wie keine Zeile im DGV und in BS selektieren?

  • VB.NET
  • .NET (FX) 4.0

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von DahProgrammah.

    DataGridView und TextBoxen an BindingSource gebunden - wie keine Zeile im DGV und in BS selektieren?

    Hallo zusammen,

    ich habe ein DataGridView (DGV) und TextBoxen an eine BindingSource (BS, diese zieht ihre Datensätze aus einer DB) gebunden - die Textboxen zeigen die Felder des jeweils im DGV selektierten Rows an, soweit so gut.
    Jetzt möchte ich initial aber keine Row in der DGV markiert haben (oder eine markierte Row programmtechnisch in bestimmten Fällen deselektieren oder der User klickt Strg+die markierte Zeile zur Deselektion der markierten Zeile), das kann ich ja mit DataGridView.ClearSelection() oder DataGridView.CurrentCell = Nothing machen.
    Die darunterliegende BS hat aber weiterhin den zuletzt markierten Datensatz als current und daher werden die Felder dieses Rows der BS in den Textboxen trotzdem angezeigt - wie kann man die Selektion der BS verhindern? Einer BS kann ich nämlich nicht sagen, dass es keinen current Satz geben soll (per .position, .move... etc.)

    Folgendes hilft (vmtl.) nicht:
    - Die Rows der Bindingsource filtern oder die Datasource abhängen - ich möchte die Datensätze der BS im DGV ja schon anzeigen, so dass man einen auswählen kann.
    - Die Texte der Textboxen bei nicht selektiertem Datensatz leeren, denn da die gebunden sind, entferne ich damit ja die Feldinhalte in der currentRow der BS.

    Ich vermute, sowas kriegt man wieder nur mit Workarounds/Klimmzügen hin, weil Microsoft den Fall, dass in einer BS nichts selektiert ist, nicht vorgesehen hat?
    Vielen Dank im Voraus.
    Schade, dass es da nichts zu geben scheint.
    Ich habe mir jetzt so beholfen, dass ich das ach so schöne DataBinding der Textboxen auf die BindingSource entfernt habe und diese jetzt manuell befülle, wenn man im DGV eine neue Zeile markiert - oder die Feldinhalte lösche, wenn man keine Zeile markiert bzw. eine Selektion programmgesteuert entfernt wird.
    Grund: Usability.

    Ich will nur dieses kleine Problem lösen: 2 Controls (Datagridview & Textfeld) sind mit einer BS verbunden, im einen selektiere ich einen Satz in der BS, das andere Zeit Daten aus dem selektierten Satz an. Habe ich keinen Satz selektiert, soll im Textfeld auch nichts angezeigt werden. Das wäre über das Binding eigentlich so schön und so einfach. Aber:

    Wenn der Anwender schon einen vorselektierten Eintrag vorfindet, aber vergisst, diesen bei Bedarf zu ändern, dann passiert eben was falsches. Ein Dirty-Flag zu setzen, das beim Auswählen eines Eintrags gesetzt wird, wäre einfach, aber wenn er genau den schon vorselektierten Wert will, wird das Flag nicht gesetzt, außer man sagt ihm, er muss etwas schon selektiertes nochmal explizit selektieren - das macht kein Mensch.
    Wäre initial kein Eintrag selektiert, kann ich das in einer Pflichtfeld-Prüfung auch abfragen und anmosern - bei einem vorselektierten Eintrag geht das nicht mehr - ist ja schon immer was selektiert.

    Eine Ähnliche Krücke findet sich bei den DateTimePickern - die brauchen auch zwingend einen Initialwert. Als Workaround hat sich Mircosoft die Sache mit der Optional dazu anzeigbaren Checkbox einfallen lassen, die ich setzen muss, um festzulegen, dass ich das enthaltene Datum verwenden möchte - dass das keiner praktisch findet, sieht man daran, dass es nirgends genutzt wird, jeder bastelt sich einen Workaround oder lebt mit dem Initialwert - letzteres will ich aus den o.g. Gründen nicht.

    DahProgrammah schrieb:

    Wenn der Anwender schon einen vorselektierten Eintrag vorfindet, aber vergisst, diesen bei Bedarf zu ändern, dann passiert eben was falsches.
    Dann isser halt selber schuld.
    Hauptsache, die Daten und ihre Anzeige sind konsistent, und bleiben das auch.
    Wie wäre es, du würdest ihm einen sinnvollen Vorschlag vor-einstellen, den er bei Gefallen nur noch abzunicken braucht?
    :D
    Jaja, dann isser selber schuld - so kann man das sehen, entspricht aber nicht meiner Ansicht von einer guten Oberfläche und Userführung.
    Es kam in der Praxis genau das geschilderte Problem vor, daher versuche ich diesen Teil aktuell zu verbessern.
    Gute Idee, aber einen sinnvollen Vorschlag gibt es einfach nicht, der Anwender hat immer alle Optionen. Ich filtere ja schon die möglichen Einträge des DGV aufgrund anderer Daten, so dass der Großteil von Falscheingaben bereits unterbunden ist.
    "Dann isser selber schuld" sage ich erst dann, wenn noch nichts markiert war und er (bewußt) etwas falsches anklickt. Wenn ich ihm aber etwas vorselektiere, sehe ich das etwas anders.
    Die Akzeptanz von Software steigt mit deren Usability. Ein Anwender, der immer wieder den gleichen Fehler macht, sieht einen Teil der Schuld auch bei der Software, die ihn hier nicht ausreichend unterstützt. Wir sprechen hier auch nicht von dem Baukasten, mit dem wir Entwickler uns rumschlagen, sondern von einer Fachanwendung mit kaum Optionen.
    Ein Anwender, der immer wieder den gleichen Fehler macht, sieht einen Teil der Schuld auch bei der Software, die ihn hier nicht ausreichend unterstützt.
    Da würde ich ihm sogar zustimmen.

    naja, dann eben workaround.
    Wie soll das vor sich gehen, dass deine Anwendung merkt: "Oh, der hat nix eingegeben!"?
    Du könntest bei DGV_GotFocus annehmen, dass er das als Eingabe meint, wenner da reinklickst.
    Und wenn wolle kannst du das Textbox-Binding auch erst dann setzen.
    Das DGV wird initial befüllt. Klicks in andere Auswahllisten führen zu einem eventuellen anschließenden Neubefüllen des DGV mit anders gefilterten Daten - dabei soll eine evtl. zuvor getroffene Markierung auch zurückgesetzt werden.

    Nach dem TableAdapter.Fill wird ja automatisch der DataGridView.SelectionChanged-Event ausgelöst und dieser abgefangen.
    Über DataGridView.Rows.GetRowCount(DataGridViewElementStates.Selected) kriegt man dazu raus, ob eine Zeile markiert ist. Hat ein anderes DGV ein Neubefüllen verursacht, wird mit DataGridView.ClearSelection() die erste automatisch oder eine durch den Anwender markierte Zeile des DGV deselektiert.
    Dann werden die o.g. (jetzt nicht mehr an die BS gebundenen) Textfelder geleert und dem der Form zugrundeliegenden Hauptdatenobjekt der Foreignkey für das zuvor ausgewählte DGV-Objekt entfernt.
    Das ist der Zustand "nichts gewählt".
    Das passiert auch, wenn man im DGV auf die markierte Zeile mit Strg klickt und sie damit direkt deselektiert - gleicher Event wie oben.

    Klickt der Anwender jetzt eine Zeile im DGV an, wird der Eintrag dem Hauptdatenobjekt zugewiesen und die Textfelder manuell mit den Feldern des gewählten Eintrags gefüllt.

    Deine Idee, die TextBox-Bindings später zu machen ist an sich interessant, bringt hier aber möglicherweise nichts - ich hab's jetzt nicht ausprobiert, denke aber, dass das Entfernen eines Bindings den Inhalt im Text trotzdem stehen lässt, dann müsste ich diesen zusätzlich manuell löschen und habe - außer etwas komplizierterem Code - nichts gewonnen.

    So, es funktioniert jetzt und bleibt so. Danke Dir für's Mitdenken!