Announcement

Collapse
No announcement yet.

Editmodus eines Winforms feststellen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Editmodus eines Winforms feststellen?

    Hallo zusammen!

    Ich habe hier ein größeres Dialogformular mit etlichen Textfeldern und einem Grid. (VS2008, C#, .NET 2.0)

    Die Daten stammen teilweise aus verschiedenen DB-Tabellen (SQL-Server), teilweise auch zur Laufzeit durch das Programm berechnet. Daher habe ich keine Felder irgendwie an die DB gebunden, sondern alle erst in einem Objekt gesammelt und dann manuell in die Textfelder übertragen.

    Nun möchte ich, dass dann, wenn der Benutzer in den Feldern Änderungen vornimmt, das Formular in einen "Editmodus" wechselt. Es soll also ein"Speichern"-Button aktiv werden, bzw. beim schliessen des Formulars soll eine Sicherheitsabfrage erfolgen.

    Meine Frage:
    wie kriege ich sicher heraus, wann sich Felder verändern?

    Aktuell habe ich mich in die Ereignisse "Textchanged" oder "Validating" gehängt und dort mühselig alle Textfelder mit dem zugehörigen Objekt-Feld verglichen. Ergibt sich irgendwo eine Veränderung, dann wird der Button enabled, ansonsten disabled.

    Dummerweise lösen die Ereignisse zu früh aus! Wenn meine Prüf-/Vergleichsroutine durchlaufen wird, fehlt immer der letzte Buchstabe des aktellen Feldes. Die letzte Eingabe in Textfeld.Text ist also in dem Moment noch nicht verarbeitet.

    Das muss doch besser gehen?

    Wie macht ihr das so?

    Als Alternative hätte ich auch noch die DevExpress-Komponenten zur Verfügung. Da gibt es etliche Properties mehr, aber da fehlt mir die Übersicht, welche hier greifen würden.
    Und ein umfangreiches Winform auf DevExpress-Komponenten umzustellen habe ich mir bisher erspart...

    Ciao,
    N.

  • #2
    Hallo,

    die Daten in Objekte einlesen ist gut. Diese Objekte können aber problemlos an die GUI gebunden werden. Somit ersparst du dir das händische übertragen.

    Bevor die Daten gebunden werden - d.h. die DataSource-Eigenschaft der BindingSource gesetzt wird - errechne ich in meinen Anwendungsfällen einen Hash des Objekts das gebunden werden soll. Es spielt keine Rolle welcher Hash-Algorithmus verwendet wird.

    Die Berechnung erfolgt derart dass das Objekt im Speicher binär serialisiert wird (MemoryStream) und daraus der MD5-Hash berechnet wird. Sollte binär nicht möglich sein da irgendwo das Serializable-Attribut fehlt kann auch XmlSerialisierung verwendet werden (oder sonst eines).

    Dieses Hash-Wert weise ich einer Variablen zu. Beim Beenden des Programm bzw. bei Prüfung auf Änderungen errechne ich erneut den Hash und vergleiche dieses mit dem ursprünglichen Wert der ja in einer Variablen gespeichert wurde.


    Hoffe du konntest meinen Ausführungen folgen. Sonst bin ich morgen wieder erreichbar.

    Gute Nacht,
    Günther
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      nun ja, die Datenbindung ist eigentlich nicht mein Problem. Ob nun manuell übertragen, oder über Bindung an ein Objekt ist eigentlich egal. Glaube ich zumindest.

      Mein entscheidendes Problem ist, wie erkenne ich den Wechsel zum Editiermodus?
      Im Moment teste ich nach jedem Tastendruck auf Gleichheit der Daten. Nur wird eben das Ereignis "Tastendruck" zu früh ausgelöst. So vergleiche ich nicht zu 100% das, was der Benutzer sieht.

      Beispiel:
      im Feld "Name" wird ein zusätzlicher Buchstabe angefügt. -> Formular geht in Editmodus.
      User hat sich vertan und nimmt den Buchstaben wieder weg. -> Formular soll wieder "normal" werden, es ist ja nichts gegenüber dem Ursprung geändert. Aber das macht mein Programm leider nicht. Das Ergeignis "Taste gedrückt" kommt zwar, aber das Textfeld liefert noch nicht den neuen String, obwohl er auf dem Bildschirm zu sehen ist.

      Ciao, (und gute Nach)
      N.

      Comment


      • #4
        Die Daten stammen teilweise aus verschiedenen DB-Tabellen (SQL-Server), teilweise auch zur Laufzeit durch das Programm berechnet. Daher habe ich keine Felder irgendwie an die DB gebunden, sondern alle erst in einem Objekt gesammelt und dann manuell in die Textfelder übertragen.
        Dieses Objekt veröffentlicht seine Daten ja wahrscheinlich als Properties. Es ist also ein leichtes die Setter der Properties so zu ergänzen das das Objekt selbst merkt das es geändert wird und einen eigenen Änderungsstatus(oder nenn das von mir aus auch Editmodus auch wenn sich das für mich falsch anhört) entsprechend setzt und veröffentlicht.

        Wenn du das Ganze per Databinding dann an die UI bindest(unter anderem auch die Statusproperty deines Objekts an die Enabled Property deines Speicherbuttons) läuft das ganze ja fast automatisch ohne das du dich mit obskuren Events der UI rumschlagen mußt.

        Comment


        • #5
          Dieses Hash-Wert weise ich einer Variablen zu. Beim Beenden des Programm bzw. bei Prüfung auf Änderungen errechne ich erneut den Hash und vergleiche dieses mit dem ursprünglichen Wert der ja in einer Variablen gespeichert wurde.
          Du meinst du implementierst IComparable und überschreibst GetHashcode oder?
          Dann würde das ganze auch sofort mit allen Listen und deren Contains, Equals etc. Funktionen funktionieren wenn du diese Objekte verwaltest.

          Comment


          • #6
            Du meinst du implementierst IComparable und überschreibst GetHashcode
            Ja, und ich erstelle die Operatoren dazu. Dann kann ich mit den Vergleichsoperatoren bequem arbeiten.

            Dieses Objekt veröffentlicht seine Daten ja wahrscheinlich als Properties. Es ist also ein leichtes die Setter der Properties so zu ergänzen das das Objekt selbst merkt das es geändert wird und einen eigenen Änderungsstatus(oder nenn das von mir aus auch Editmodus auch wenn sich das für mich falsch anhört) entsprechend setzt und veröffentlicht.
            Diest hat nur einen (kleinen) Nachteil: Wird eine Änderung zurückgenommen so dass alle öffentlichen Eigenschaften dieselben Werte wie ursprünglich haben wäre die Eigenschaft für Änderung trotzdem gesetzt. Dies zu prüfen wäre wieder aufwändiger und deshalb habe ich aus dieser Überlegung die Hash-Variante entwickelt.

            mfG Gü
            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

            Comment


            • #7
              Du meinst du implementierst IComparable und überschreibst GetHashcode oder?
              Originally posted by gfoidl View Post
              Ja, und ich erstelle die Operatoren dazu. Dann kann ich mit den Vergleichsoperatoren bequem arbeiten.
              Bahnhof??? Koffer geklaut???

              Leider sagt mir das alles herzlich wenig.
              Dummerweise bin ich heute anderweitig beschäftigt worden. Aber am Wochenende werde ich mal alle Ereignisse des Forms durchgehen. Irgendeines muss doch nach dem aktualisieren der Textfelder aufgerufen werden...

              Ich glaube immer noch, dass meine eigene (einfache) Idee nicht schlecht ist.

              Andererseits lässt sich die Prüfroutine vermutlich auch direkt in das Datenobjekt einbinden. Die Originaldaten zum Vergleich zu speichern ist in diesem Fall nicht so aufwändig. Nur eine Fleissarbeit mit Cut and Paste.

              Erst mal danke für die Antworten.

              Ciao,
              N.

              Comment


              • #8
                Andererseits lässt sich die Prüfroutine vermutlich auch direkt in das Datenobjekt einbinden.
                Das entspricht der Antwort von Ralf.

                Bahnhof??? Koffer geklaut???
                Entspricht meiner ersten Antwort nur in "Fachchinesisch" ausgedrückt.

                Ich glaube immer noch, dass meine eigene (einfache) Idee nicht schlecht ist.
                Hab ich in meinen ersten Beispielsanwendungen auch so gelöst. Mit der Zeit entwickelte sich jedoch mein Vorschlag. Dieses Muster ist außerdem wiederverwendbar, d.h. kann in anderen Anwendungen ohne viel Aufwand eingesetzt werden.

                mfG Gü
                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                Comment

                Working...
                X