मुझे यह समस्या भी थी। मैंने इसे "द ममेन्टो पैटर्न डिजाइन" का उपयोग करके हल किया। इस पैटर्न के साथ आप अपने मूल ऑब्जेक्ट की एक प्रति और selectedIndexChange
(नियंत्रण के) या रद्द बटन में आसानी से सहेज सकते हैं, आप अपने ऑब्जेक्ट के पहले संस्करण को आसान बना सकते हैं।
हम गुणों के साथ एक वर्ग उपयोगकर्ता है, तो पासवर्ड उपयोगकर्ता नाम और NombrePersona हम तरीकों CreateMemento और SetMemento जोड़ने की जरूरत:
इस पद्धति के उपयोग का एक उदाहरण How is the Memento Pattern implemented in C#4?
कोड का एक उदाहरण पर उपलब्ध है
:
public class Usuario : INotifyPropertyChanged
{
#region "Implementación InotifyPropertyChanged"
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private String _UserName = "Capture su UserName";
public String UserName
{
get { return _UserName; }
set { _UserName = value; RaisePropertyChanged("UserName"); }
}
private String _Password = "Capture su contraseña";
public String Password
{
get { return _Password; }
set { _Password = value; RaisePropertyChanged("Password"); }
}
private String _NombrePersona = "Capture su nombre";
public String NombrePersona
{
get { return _NombrePersona; }
set { _NombrePersona = value; RaisePropertyChanged("NombrePersona"); }
}
// Creates memento
public Memento CreateMemento()
{
return (new Memento(this));
}
// Restores original state
public void SetMemento(Memento memento)
{
this.UserName memento.State.UserName ;
this.Password = memento.State.Password ;
this.NombrePersona = memento.State.NombrePersona;
}
फिर, हम एक वर्ग मेमेंटो है कि इस तरह हमारे वस्तु की "कॉपी" में शामिल होंगे की जरूरत है
/// <summary>
/// The 'Caretaker' class
/// </summary>
class Caretaker
{
private Memento _memento;
// Gets or sets memento
public Memento Memento
{
set { _memento = value; }
get { return _memento; }
}
}
तब के लिए इस पैटर्न लागू हम Caretaker
वर्ग का एक उदाहरण
Caretaker creadorMemento = new Caretaker();
बना सकते हैं और बनाने के लिए:
और हम एक वर्ग है कि पैदा करते हैं और हमारे स्मृति चिन्ह वस्तु शामिल होगा की जरूरत है जब हमारे द्वारा चयनित उपयोगकर्ता को प्रारंभ करने के बाद selectedIndexChange
में उदाहरण के लिए चुना गया था, तो हमारी स्मृति वस्तु ऑब्जेक्ट का चयन किया गया था, उदाहरण के लिए मैं RaisPropertyChanged
ईवेंट के लिए विधि का उपयोग करता हूं:
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
if (prop == "RowIndexSelected") // This is my property assigned to SelectedIndex property of my DataGrid
{
if ((this.UserSelected != null) && (creadorMemento .Memento != null))
{
this.UserSelected.SetMemento(creadorMemento .Memento);
}
}
if (prop == "UserSelected") // Property UserSelected changed and if not is null we create the Memento Object
{
if (this.UserSelected != null)
creadorMemento .Memento = new Memento(this.UserSelected);
}
}
इस के लिए एक व्याख्या है, जब selectedIndexChanged
परिवर्तन मूल्य हम जाँच अगर UserSelected
और our memento object
अशक्त नहीं हैं इसका मतलब है कि संपादन मोड में हमारी वास्तविक मद तो बदल गया है हम विधि SetMemento
के साथ हमारे वस्तु पुनर्स्थापित करने के लिए है। और यदि हमारे UserSelected
संपत्ति में परिवर्तन और शून्य नहीं है तो हम "हमारे Memento ऑब्जेक्ट बनाएं" का उपयोग करेंगे जब हम संपादन रद्द कर देंगे।
खत्म के लिए, हम हर विधि है कि हम संस्करण को रद्द करने की जरूरत है SetMemento
विधि का उपयोग किया है, और हम इस this.creadorMemento = null
तरह अशक्त हमारे स्मृति चिन्ह वस्तु निर्धारित कर सकते हैं जब संपादित SaveCommand में तरह प्रतिबद्ध है।
IEditableObject आपकी ऑब्जेक्ट्स के लिए बहुत अधिक ओवरहेड बनाता है, खासकर यदि आपकी मॉडल ऑब्जेक्ट्स क्लास हैं और स्ट्रक्चर नहीं है, तो आपको इसका समर्थन करने के लिए अपने मॉडल ऑब्जेक्ट्स को फिर से लिखना होगा। – Agies
@ एजीज: डाउनवोट क्यों? चाहे IEDitableObject एक "बहुत अधिक ओवरहेड" है या नहीं, पूरी तरह से आपके आधारभूत संरचना पर निर्भर करता है या आप इसे कैसे कार्यान्वित करना चाहते हैं। यह सिर्फ एक इंटरफेस है कि डब्ल्यूपीएफ समझता है। आप इसे कैसे लागू करते हैं आप पर निर्भर है। –
+1, हाँ, मैं इसे IEDitableObject के साथ कार्यान्वित करना चाहता हूं, लेकिन मेरे पास एक ViewModelBase है जो एक संपत्ति का खुलासा करता है टाइप प्रकार टीएमओडेल और मैं सीधे खुला मॉडल के गुणों पर दृश्य को बांधता हूं। अब मैं अभी भी 'संपादन रद्द करें' का उपयोग कैसे कर सकता हूं, अब भी, कि आप मेरे परिदृश्य को जानते हैं, कहें कि मेरा टीएमडेल एक पता इकाई है। व्यू मोड में यह सिर्फ फुलएड्रेस लाइन से जुड़ा हुआ है और एड्रेसडाटा टेम्पलेट (जीमैप्स के लिए लिंक बनाना) का उपयोग करता है, लेकिन मैं चाहता हूं कि जब उपयोगकर्ता एड्रेस व्यू पर एडिट बटन पर क्लिक करता है, तो उसे एक चाइल्डविंडो (एसएल, या डब्ल्यूपीएफ में जो भी विंडो खोलनी चाहिए) जारी रखने के लिए ... –
Shimmy