Bindingsource.Current erst bei Doppelklick setzen

  • VB.NET

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von fichz.

    Bindingsource.Current erst bei Doppelklick setzen

    yo Leute,

    ich ein doofes (hoffe aber simples) Problem.
    Ich habe ein Splitpanel wo auf der linken Seite ein Grid ist und rechts die Details (Benutzerverwaltung)

    In dem Grid zeig ich nur den Benutzername und den Nachnamen an und bei den Details halt alles.

    Nun zu meinem Problem:
    Die Details sind an ein Bindingsource gebunden und wenn ich links im Grid einen Eintrag auswähle werden auch gleich die TextBoxen, Checkboxen, etc. korrekt geändert.
    Nur will ich das nicht bei einem Klick machen sondern erst bei einem Doppelklick.

    Ist das irgendwie möglich?

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    also Databinding ist, wenn der DetailView mit der auswahl der Liste synchron ist.
    Erst bei Doppelklick zu aktualisieren dürfte die meisten User irritieren, durch die inkonsistenz der Darstellung links und rechts.

    Was schönes dazu weiß ich nicht, weil ich son Gui nicht schön fände.
    Annere Möglichkeit wäre, auf Doppelklick hin ein gesondertes Form modal zu öffnen - das wäre wieder eine konsistente Präsentation.
    Ok hab mich nun dazu entschlossen es auf die gewöhnliche Art zu machen. Also Links und rechts synchron (ohne dem Doppelklick).
    Jedoch hab ich hier noch ein kleines Problem.

    Ich will, dass immer nur 1 Datensatz geändert werden kann. Wurden Änderungen durchgeführt, so muss man diese entweder speichern oder verwerfen (hab hierzu eine Toolbar oben in der Form). Diese Toolbar ändert sich je nach Zustand:
    - Beim Start der Form ist zB ein Hinzufügen Button aktiv, jedoch ist Speichern, Löschen und Abbrechen deaktiviert.
    - Beim Anzeigen eines Datensatzes wird zusätzlich der Löschen Button dazugeschalten.
    - Beim Ändern eines Datensatzes wird der Hinzufügen deaktiviert alle anderen jedoch aktiviert (Speicher, Löschen, Abbrechen).

    Ich bekomm es jedoch nicht gebacken den aktuellen Status zu ermitteln.
    Das CurrentItemChanged Event feuert auch wenn ich links zwischen den Datensätzen wechsle. Frag ich noch dazu die IsEdit Property der Current-Row ab steht die auch sofort auf True.

    Wie kann ich unterscheiden ob nur der Datensatz gewechselt wurde und ob dieser auch wirklich verändert wurde? Ich brauche diese Info damit ich links die Auswahl sperren kann bis entweder gespeichert oder abgebrochen wurde.

    lg

    EDIT: gerade gesehen, dass das CurrentItemChanged-Event NUR mehr feuert wenn ich die Auswahl verändere. Es finde kein Event welches feuert, wenn sich einfach ein Wert ändert...
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten

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

    Das funktioniert leider auch nicht wie erhofft. Sobald ein anderer Datensatz ausgewählt wird, feuert bspw. auch das TextChanged Event von der TextBox.

    Wie verwendet man den standardmäßig solch Schemas mit DataSets? An sich will ich es gerne verwenden, da es mir viel Arbeit abnimmt, anderseits wird mir das mit dem Databinding immer unsympathischer wenn es nach jeder Kleinigkeit irgendwelche Probleme gibt...

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    ja, das wird kompliziert, weils drauf hinausläuft, ein eigenes IsInEditMode zu schreiben. Die Changed-Events dürfen erst bei SplitPanel2_GotFocus aktiviert werden, und der IsInEditMode muss ja auch wieder ausgeschaltet werden und so Zeugs.

    Deine "Kleinigkeit" ist halt ein fragwürdiger aussergewöhnlicher Sonderwunsch, und das kostet, so oder so: ob du nun mit Databinding fährst oder ohne.

    Vom Databinding vorgesehener Standard ist eben, dass beim Wechsel des Datensatzes die in Controls evtl. gemachten Änderungen automatisch ins Dataset geschrieben werden (übrigens noch nicht in die Datenbank!). Also implizit wird der EditModus betreten, und implizit auch wieder verlassen.

    Alternativ kann man ein spezielles modales Edit-Form aufpoppen lassen (zB auf Doppelklick) - sodass der User explizit den EditModus betritt und explizit wieder verlässt (Ok- oder Cancel-Button schließt das Edit-Form).
    Ebensogut kann man auch auf Doppelklick hin den DetailView erst beschreibbar machen und die Datensatz-Anwahl so lange deaktivieren - ist ja das gleiche: Der User betritt und verlässt explizit den EditModus.

    Was du aber willst ist, dass der User den Editmodus implizit betritt, wenn er in einem Control eine Änderung macht, und ihn dann nur noch explizit wieder verlassen kann.
    Sorry - diese Kleinigkeit ist halt nicht vorgesehen - ist machbar, kostet halt Aufwand.
    Hm kompliziert kompliziert... Muss ich mir mal durchn Kopf gehen lassen ob ich das so haben will.

    Anfangs hatte ich einen anderen Ansatz. Mich um das ganze Binding und Table Zeugs selbst zu kümmern (fand ich an sich auch nicht schlecht, aber dachte mit DataSet funktioniert es besser).
    Es funktioniert auch genau so wie ich es mir dachte, nur muss ich halt den Code je Tabelle selbst coden.

    Basis davon war eine abstrakte Basisklasse wo die Datenbankmethoden wie Select, Delete, Insert und Update von der abgeleiteten Klasse überschrieben werden mussten.
    Intern wurde geregelt wann der Datensatz geändert worden war über das Interface INotifyPropertyChanged.

    Die linke Seite wurde über eine List(Of) der relevanten Einträge gehandelt. Somit hatte ich alle Einträge welche ich haben will.
    Bei einem Doppelklick auf ein Item wurde es aus der List(of) in ein einzelnes Objekt gecastet auf welchem das Databinding im rechten Bereich basiert.
    Über das INotifyPropertyChanged Event wusste ich wann ein Eintrag geändert wurde und konnte so meine Toolbar setzen.

    Vorteil von dem ist, dass ich halt alles selber steuern kann.
    Nachteil daran ist halt, dass ich mich um alles selbst kümmern muss. Gerade auch das, dass alles korrekt weggeschrieben wird.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Du wolltest also das Rad neu erfinden, weil du denkst, dann kannst du alles besser steuern.

    Das Rad ist numal schon erfunden, und funktioniert hervorragend. Und du kannst damit ebenfalls alles steuern, nur: statt dein eigenes Rad zu erfinden, musste den Umgang mit dem Standard-Rad erlernen.
    Das ist auch aufwändig, aber vermutlich weniger aufwändig als das Selbst-Erfinden.
    Und du lernst viel mehr dabei, und wirklich neues, als wenn du nur deine bisherigen Kenntnisse in deiner Eigen-Erfindung reproduzierst.
    Und das Ergebnis ist leistungsfähiger und läuft stabiler.
    Das war ja auch mein Gedanke.

    Ich muss halt jetzt abwägen, ob dieses "neue" System, dass man mehrere Datensätze ändern kann, für uns in Frage kommt, da es das so in der Art noch nicht gegeben hat.
    Es war bei uns immer Schema Datensatz ändern -> speichern, usw. welches ich persönlich auch schöner finde, da man hier genau weiß: Ich ändere DIESEN Datensatz.

    Es würde mir halt schon reichen, dass man nur 1 Datensatz ändern kann und diesen eben speichern oder verwerfen muss.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    kannst du ja - beim expliziten, bestätigenden Verlassen des EditModus (egal wie das umgesetzt ist) ist dann halt die Speichern-Routine aufzurufen.

    Nützlich wäre halt eine allgemeine Speichern-Routine, die alle Changes speichert, ob das nun ein einziger Datensatz ist, oder 200, aus nur einer Tabelle, oder aus 5 verschiedenen - das kann der Routine schnurz sein - anhand der Änderungsverfolgung kann man das ein für allemal abhandeln, sogar ganz allgemein für jede Datenbank.
    Weiß jetzt nicht genau wie du das meinst :S
    Den Editmodus verlasse ich ja schicht mit EndEdit/CancelEdit der Bindingsource oder? Hier will ich ja schon eine Abfrage machen ob der Datensatz nun gespeichert werden soll oder nicht. (Hier würde ich auch schon ein Datenbankupdate machen)
    Nur das will ich halt nur dann fragen wenn sich auch was geändert hat. Im Editmodus ist er ja sobald ich einen Datensatz auswähle obwohl ich noch nix geändert habe. Verstehe hier die Logik der Bindingsource nicht so ganz.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    @fichz
    An der Problematik hab' ich mir auch schon einmal die Finger wundgecodet ... und schliesslich alles über den Haufen geworfen, und schlicht normales Databinding, assistentengestützt, verwendet.
    Erfassen und ändern von Datensätzen erfolgt in modalen Formen, damit hab' ich alles unter Kontrolle.
    Was vielleicht noch wichtiger ist: Der Endbnutzer erkennt Standardabläufe wieder und wird nicht mit neuen Abläufen konfrontiert.
    @us4711: Es ist zum Haaresupfen ja... Denke aber habe nun eine Methode gefunden wies funktioniert (siehe unten).

    @ErfinderDesRades: Hatte diesen Post nicht zu 100% verstanden, mittlerweile meine ich aber zu verstehen was du meinst. Ich hab es nun folgendermaßen umgesetzt:

    - Databinding ist anfangs nur mehr in der linken Spalte (Auswahl der Benutzer) bereits im Designer gesetzt, rechts (Detail) ist kein Datenbinding jedoch nicht mehr.
    - Bei Doppelklick auf das einen Eintrag (links in Auswahl) wird das aktuelle (.Current) der Bindingsource in eine BedienerRow gecatstet. Anschließend wird manuell das Databinding hinterlegt per control.Databindings.add. Das wunderbare an dieser Variante des Databindings ist, dass man hier als UpdateMode NotifiyPropertyChanged auswählen kann und das auch funktioniert (!!!). Wählt man es im Designer aus hatte es nämlich keine Auswirkung.
    - Das ListChanged Event der Bindingsource feuert nun auch sobald sich eine Eigenschaft ändert (reicht aus wenn bei TextBox 1 Zeichen geändert wird).
    - Durch diese Info kann ich alles so setzen wie ich es will.

    Vorteile mMn. an dieser Methode.
    - Es läuft vollständig über das DataSet was meine selbst erstellten Klassen komplett ablöst.
    - Es ist alles vollständig per Databinding gelöst (wenn auch selbst hinzugefügt)
    - Ich kann meine Logik, wie sie bei uns üblich ist, vollständig ausleben.

    Ich hoffe bei dieser Methode nun auf einen Erfolg :)

    Gibt es hierbei noch etwas zu beachten?

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Das ist nun eine Form des expliziten Übergangs in den Editmode.
    Das kann man wesentlich einfacher haben.
    Du kannst den DetailView an eine geeignete extra-BindingSource binden - im Designer - geht ganz problemlos.
    Dieser BindingSource weist du beim Doppelklick selectorBindingSource.Current als DataSource zu - kein weiteres Herumstöpseln an den Controls ist dafür nötig.

    Auch DataSourceUpdateMode.OnPropertyChanged kannst du bequem im Designer einstellen - ein für allemal.
    Musste halt bei den Bindungs-Einstellungen des Controls auf "Erweitert" gehen.

    ErfinderDesRades schrieb:

    Auch DataSourceUpdateMode.OnPropertyChanged kannst du bequem im Designer einstellen - ein für allemal.

    Geniale Idee eine eigene Bindingsource dafür zu machen. Problem jedoch auch wenn ich OnPropertyChanged auswähle passiert nichts wenn ich eine Eigenschaft ändere.

    Ich vermute es liegt auch nicht daran ob Designer oder Code, es liegt an der Bindingsource.
    Ich habe nun beide Varianten probiert. Einmal Bindingsource mit OnPropertyChanged und einmal als BedienerRow mit OnPropertyChanged.
    Bei der BedienerRow funktioniert es wie gewollt, bei Bindingsource wird erst gefeuert wenn ich einen anderen Datensatz auswähle.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    hier ein dubbeliges Beispiel - Artikel kann man editieren nach Doppelklick im ArtikelGrid.
    Ich halte ja den expliziten EditMode über das Artikel-Menü für die bessere Benutzerführung, zumal die ebenso auch das Hinzufügen abdeckt.

    Wozu du DatasourceUpdateMode.OnPropertyChanged brauchst ist mir dabei unklar.
    Dateien

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

    Das ist die Möglichkeit in die andere Richtung (welche natürlich auch gehen würde).
    Ich wollte es aber so haben, sobald sich ein Wert ändert, soll (um bei deinem Beispiel zu bleiben) das Grid oben rechts deaktiviert werden.

    Das schaff ich jedoch nur, wenn ich als Binding die aktuelle Row mit OnPropertyChanged verwende, da hier, sobald sich ein Wert ändert, das ListChanged Event gefeuert wird und ich das Grid deaktivieren kann.

    lg

    EDIT:
    Habs mal angehängt wie ich es meine.
    Sehr proffesorisch, da man hier nur einmal Doppelklick + Ändern kann. Nur um es zu verdeutlichen. Hoffe du kannst es öffnen. Hab es mit 2013 bearbeitet kam aber keine Konvertierungsmeldung.

    lg
    Dateien
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten

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