Laden...

Referenztyp: im Bearbeitenfenster soll nur bei OK die Änderung übernommen werden

Erstellt von Campy vor 12 Jahren Letzter Beitrag vor 11 Jahren 6.105 Views
C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 12 Jahren
Referenztyp: im Bearbeitenfenster soll nur bei OK die Änderung übernommen werden

Hallo zusammen,

ich übergebe in meiner Anwendung ein Objekt aus einer Liste an ein Fenster zum Bearbeiten (Das Objekt ist ein Referenztyp).
Bis jetzt war es so, dass beim schließen des Fensters die Änderungen am Objekt automatisch gespeichert werden sollen. Nun soll ein "Ok" und "Abbrechen" Button eingeführt werden und nur beim Klick auf den "Ok" Button gespeichert werden (Was auch kein Problem ist), jedoch übernimmt die Liste ja die Änderungen des Objekts was ich verhindern möchte.

Wie mache ich das am besten??

A programmer is just a tool, which converts coffeine into code! 🙂

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

verwende bei der Bindung die Einstellung UpdateSourceTrigger=Explict und nur beim OK wird BindingExpression.UpdateSource aufgerufen. Das ist m.E. der einfachste Weg.

Sonst entweder per Undo*, geklontes Objet übergeben und bei Cancel wieder zurückklonen, etc. ==> wie sich in den Folgeposts zeigt durch Verwendung von IEditableObject

* Multilevel-Undo/-Redo mit dem Command-Muster

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 12 Jahren

Hallo gfoidl,

es handelt sich um eine MVVM Anwendung.
Mein Problem ist nun, wie Rufe ich die "BindingExpression.UpdateSource" - Methode aus dem ViewModel der Liste (hier weiß ich ob gespeichert wird oder nicht) auf?

A programmer is just a tool, which converts coffeine into code! 🙂

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

Edit: das ist nicht die 1. Wahl (war gestern wohl blind) - siehe unten

ich würds einfach im Code-Behind machen - ist ja eine UI-Sache (die Anzeige entweder in die Objekte schreiben oder nicht).
Eine weiterführende Betrachtung liefert zB UpdateSourceTrigger = "Explicit" for MVVM Puritans (wobei mir dieser Ansatzt fast besser gefällt).

PS: hier merkt man wieder einmal wie leicht bestimmte Dinge mit WPF geworden sind 😃

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

I
279 Beiträge seit 2008
vor 12 Jahren

Ich würde im ViewModel, IEditableObject implementieren 😃

5.742 Beiträge seit 2007
vor 12 Jahren

Ich würde im ViewModel, IEditableObject implementieren 😃

Ja!
Am besten noch in Kombination mit IDataErrorInfo und man kann vor dem Speichern noch schön alles validieren.

UpdateSourceTrigger ist IMHO ein Designfehler der WPF.

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 12 Jahren

Alles klar! Werde ich heute Abend gleich mal machen 😃
IDataErrorInfo verwende ich bereits 😉

A programmer is just a tool, which converts coffeine into code! 🙂

I
279 Beiträge seit 2008
vor 12 Jahren

Ja!
Am besten noch in Kombination mit IDataErrorInfo und man kann vor dem Speichern noch schön alles validieren.

*Zustimm*

Funktioniert bei WPF dank DataBinding noch viel schöner als bei WinForms .-)

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo winSharp93,

UpdateSourceTrigger ist IMHO ein Designfehler der WPF.

Zumindest bei Explicit gebe ich dir recht - hab gestern da wohl nix nachgedacht.
So wäre es ja nicht mal testbar. Danke für das wieder in Errinnerung rufen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 12 Jahren

Hallo,

habe das IEditableObject Interface nun erfolgreich implementiert und es würde auch mit Sicherheit funktionieren, aber ich brauche ja eine echte Kopie meines Objekts (Referenztyp), verwende ich hierfür nen DeepClone oder gibt es bessere Möglichkeiten?

Ich kenne nur folgenden DeepClone aus früheren Zeiten, aber ich kann ja garnicht alle verwendeten Objekte (OnPropertyChanged Eventhandler) als [Serializeable] markieren... Noch dazu ist das ganze nicht typsicher 😦


public static object DeepClone(object obj)
        {
            object objResult = null;
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                ms.Position = 0;
                objResult = bf.Deserialize(ms);
            }
            return objResult;
        }

A programmer is just a tool, which converts coffeine into code! 🙂

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

das Memento-Muster bietet sich hier an. ModalDialogs, IEditableObject and MVVM zeigt eine Implementierung davon.

Die von dir gezeigte Möglichkeit zerstört die Identität des Objekts und von daher ist es besser nur den Zustand zu speichern und ggf. wieder herzustellen. All das geht mit dem Memento relativ einfach.
BTW: eine generische Version wäre benutzerfreundlicher 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 12 Jahren

Perfekt!!!
Verwende die ModalDialogs eh schon im ganzen Projekt, und Momento ist jetz genau noch mein letztes fehlendes Puzzlestück 😃

Vielen Dank! Wieder jede Menge gelernt 😃
MFG Campy

EDIT: Funktioniert wirklich super!

A programmer is just a tool, which converts coffeine into code! 🙂

C
1.214 Beiträge seit 2006
vor 12 Jahren

Ich möchte das Thema wieder aufgreifen, weil ich das auch grad brauche. Ist die Lösung nicht etwas zu einfach? Verwendet den Ansatz jemand in großen Real Life Projekten?
An sich find ich den Ansatz mit IEditableObject und dem generischen Memento ja ganz nett. Aber mir geht das nicht weit genug und wenn ich anfange, das für bestimmte Problemstellungen abzuwandeln, wird es schnell inkonsistent.
Was mach ich zum Beispiel mit Eigenschaften, die Listen darstellen? Und was ist mit Listen, die nicht nur im Speicher liegen, sondern auch Abhängigkeiten im Dateisystem haben? Ich finde, die Beispiele im Netz sind jetzt etwas zu einfach... Hat jemand vielleicht mal ein größeres Projekte mit WPF mit ähnlichen Anforderungen umgesetzt?

F
10.010 Beiträge seit 2004
vor 12 Jahren

Man findet immer Mittel und Wege den Std weg als falsch darzustellen.
Es ist nicht die Aufgabe der IEditableObject und IDataErrorInfo Interfaces ganze Businesslogiken zu kapseln, sondern lediglich beim editieren eines einzelnen Objekts behilflich zu sein.

Willst du mehr machen, musst du dir mal TransActionScope anschauen.
Damit kannst du sowas erledigen.

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 11 Jahren

Hallo zusammen,

ich bin gerade an der Weiterentwicklung der alten Software, für die ich das Momento-Muster eingesetzt hatte.

Wie von Coder007 angesprochen, stehe ich nun wirklich vor dem Problem, dass an dem Objekt eine Liste "hängt" die auch im Bearbeitungsfenster bearbeitet werden kann.

Ich habe es dann mit einer TransactionScope versucht, leider klappt dies nicht:


using (TransactionScope transaction = new TransactionScope())
                {
                    var vm = new ViewModel.ViewModel(base.Services, this.SelectedItem);
                    var vw = new ViewView(vm);


                    ModalDialogService.Service.Show(vw, vm, p =>
                    {
                        try
                        {
                            if (vm.WindowResult)
                            {

                                using (base.Services.svc= base.Services.svcClientFactory.Create())
                                {
                                    base.Services.svc.Save(vm.Item);
                                    transaction.Complete();
                                }

                            }
                        }
                        catch (FaultException<myException> fault)
                        {
                        }
                        catch (Exception ex)
                        {
                        }
                    });
                }

Ich hoffe ihr könnt mir weiterhelfen! Danke!

A programmer is just a tool, which converts coffeine into code! 🙂

F
10.010 Beiträge seit 2004
vor 11 Jahren

Das TransactionScope macht nichts von alleine, das verhalten musst du schon selber implementieren, es gibt dir nur die Interfaces.

Nur wo ist hier dein Problem?

ViewModel sagt doch schon alles aus.
Du bist dafür zuständig im ViewModel ( dafür ist das gedacht ) die zu bearbeitenden Daten so aufzubereiten das sie ggf verworfen werden können.
Wenn dir das händische zu viel Arbeit ist, nimm MicroModel oder bau dir etwas ähnliches.

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 11 Jahren

Hallo FZelle,

ich habe die TransactionScope bis jetzt nur im Zusammenhang mit dem EntityFramework verwendet.

Kannst du mir sagen, was ich für meine eigenen Objekte implementieren muss damit das funktioniert?

Vielen Dank!
Campy

A programmer is just a tool, which converts coffeine into code! 🙂

F
10.010 Beiträge seit 2004
vor 11 Jahren

Wozu, was willst Du erreichen?

Transactionscope ist gedacht für Aktionen die mehrer getrennte externe Speicheraktionen durchführen die dann ggf rückgängig gemacht werden sollen.

Wo machst du das in deinem Code?
Du speicherst hier an einer einzelnen stelle mehrere Objekte.
Wäre da nicht ein einfaches Memento besser?
Oder ein "normales" Undo/Redo Framework?

Aber wenn du dir anschauen willst was für TransactionScope alles gemacht werden muss, Volatile Resource Managers in .NET Bring Transactions to the Common Type

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 11 Jahren

Hallo FZelle,

ich verwende momentan einen Momento, allerdings kommt der nur mit simplen Datentypen der Properties zurecht, nicht aber mit List<> 😦
Gibt es für dieses Problem Abhilfe oder muss ich einen Redo / Undo Manager verwenden? Wenn ja, gibt es Empfehlungen?

Vielen Dank
Campy

A programmer is just a tool, which converts coffeine into code! 🙂

F
10.010 Beiträge seit 2004
vor 11 Jahren

Wenn dein Memento keine Listen unterstützt ist das deine Begrenzung, aber keine grundsätzliche.
Schon das simple MicroModel kann dir auch für Listen ein ViewModel erstellen.

C
Campy Themenstarter:in
439 Beiträge seit 2008
vor 11 Jahren

Schon das simple MicroModel kann dir auch für Listen ein ViewModel erstellen.

Ja schon, aber das bringt mich ja bei meiner Problematik mit Undo / Redo nicht weiter?!

A programmer is just a tool, which converts coffeine into code! 🙂

F
10.010 Beiträge seit 2004
vor 11 Jahren

Warum nicht?
Wenn du mal nach MicroModel und IEditableObject suchst ( hab ich mal 2 Minuten gemacht ) wirst du z.b. auf
IEditableObject Adapter for WPF and Windows Forms und Editable Collection Adapter for WPF stossen.

Sourcen gibt es hier https://bitbucket.org/paulstovell/samples/src