2011-11-03 10 views
12

मुझे पता है कि एमवीवीएम भारी रूप से INotifyPropertyChanged का उपयोग करता है, लेकिन मैंने कभी भी INotifyPropertyChanging का कोई उपयोग नहीं देखा है। कोई कारण क्यों?कोई भी INotifyPropertyChanging का उपयोग क्यों नहीं करता?

यदि मैं इसका उपयोग करना चाहता हूं, तो यह मेरे एमवीवीएम फ्रेमवर्क में इसे एकीकृत करने का एक अच्छा तरीका क्या होगा? मुझे पता है कि आपको अपने ViewModel पर MessageBox का उपयोग नहीं करना चाहिए क्योंकि तब आप इकाई का परीक्षण नहीं कर सकते हैं। तो कोई चेतावनी फेंकने के बारे में कैसे जाएगा, फिर लागू होने पर PropertyChange के साथ जारी रहेगा?

+1

आप यहां क्या हासिल करना चाहते हैं? यह जानने के लिए उपयोग का मामला क्या है कि संपत्ति कब * बदलने के बारे में है? – ChrisF

+0

उपयोगकर्ता को सत्यापित करने के लिए "क्या आप निश्चित हैं?" कुछ बदलावों के लिए ... हम यह सुनिश्चित करना चाहते हैं कि व्यवस्थापक का मतलब उपयोगकर्ता के उपयोगकर्ता नाम/लॉगिन को बदलना है और उन्होंने गलती से क्षेत्र को अपडेट नहीं किया है। – michael

उत्तर

11

INotifyPropertyChanging के बारे में कुछ ध्यान में रखना है कि आप को होने से होने वाले परिवर्तन को रोक नहीं सकते हैं। यह आपको केवल यह रिकॉर्ड करने की अनुमति देता है कि परिवर्तन हुआ।

मैं इसे परिवर्तन ट्रैकिंग के लिए खान के ढांचे में उपयोग करता हूं, लेकिन यह परिवर्तनों को रोकने के लिए उचित तरीका नहीं है। इस बिंदु पर

delegate void AcceptPendingChangeHandler(
    object sender, 
    AcceptPendingChangeEventArgs e); 

interface IAcceptPendingChange 
{ 
    AcceptPendingChangeHandler PendingChange; 
} 

class AcceptPendingChangeEventArgs : EventArgs 
{ 
    public string PropertyName { get; private set; } 
    public object NewValue { get; private set; } 
    public bool CancelPendingChange { get; set; } 
    // flesh this puppy out 
} 

class ViewModelBase : IAcceptPendingChange, ... 
{ 
    protected virtual bool RaiseAcceptPendingChange(
     string propertyName, 
     object newValue) 
    { 
     var e = new AcceptPendingChangeEventArgs(propertyName, newValue) 
     var handler = this.PendingChange; 
     if (null != handler) 
     { 
      handler(this, e); 
     } 

     return !e.CancelPendingChange; 
    } 
} 

आप अपना दृश्य मॉडल के लिए सम्मेलन द्वारा इसे जोड़ने की आवश्यकता होगी::

आप एक कस्टम इंटरफेस/घटना जोड़ी के साथ अपने ViewModelBase का विस्तार कर सकता है

class SomeViewModel : ViewModelBase 
{ 
    public string Foo 
    { 
     get { return this.foo; } 
     set 
     { 
      if (this.RaiseAcceptPendingChange("Foo", value)) 
      { 
       this.RaiseNotifyPropertyChanging("Foo"); 
       this.foo = value; 
       this.RaiseNotifyPropretyChanged("Foo"); 
      } 
     } 
    } 
} 
1

दूसरे प्रश्न का उत्तर देने के लिए, आप हमेशा अपने वीएम को इंटरफेस (इनोटिफायर?) पर भरोसा करने के लिए निर्भरता इंजेक्शन पैटर्न का उपयोग कर सकते हैं और एक ठोस कार्यान्वयन में गुजर सकते हैं जो संदेशबॉक्स को पॉप अप करता है। यह यूनिट-टेस्टेबिलिटी बरकरार रखता है।

संपादित करें: पहला प्रश्न शायद एसओ के लिए भी व्यक्तिपरक है। इंटरफ़ेस का इरादा स्पष्ट है लेकिन इसका उपयोग कब किया जाए, यह बहुत विशिष्ट उपयोग मामलों के लिए होगा। निर्भरता गुण कुछ समान उठाते हैं और यह लागू करने से पहले नया मान मान्य करने के लिए उपयोगी हो सकता है लेकिन यदि आप सरल गुणों का उपयोग कर रहे हैं तो आप अधिक आसानी से अपने सेटटर के अंदर यह चेक डाल सकते हैं। यदि किसी भिन्न घटक को वैधता की जांच करने की आवश्यकता होती है तो यह सामान्य रूप से सरल होगा यदि उस घटक ने स्वयं परिवर्तन किया (नए मान को सत्यापित करने के बाद) या परिवर्तन करने वाले घटक द्वारा किए गए परिवर्तन को सत्यापित करने के लिए स्पष्ट रूप से बुलाया गया था।

-6

आप की जरूरत है INotifyProperty उदाहरण के लिए बदलें यदि आप जानना चाहते हैं कि कोई वैरिएबल कब बदला जाएगा क्योंकि आप PropertyChangedEventHandler का उपयोग कर सकते हैं। इस तरह से यदि आप किसी भी gui तत्व पर बंधे किसी निर्भरता संपत्ति को प्रोग्राम चलाते समय गुई को फिर से लोड कर सकते हैं।

अंतिम प्रश्न के लिए मुझे लगता है कि आप अपने परिभाषित संदेशों के साथ एक लॉग फ़ाइल लिख सकते हैं और यदि आप उपयोगकर्ता को कोई चेतावनी दिखाना चाहते हैं तो आप त्रुटि सारांश या टूलटिप्स जैसे नियंत्रणों का उपयोग कर सकते हैं। लेकिन अगर आपको केवल परीक्षण के लिए इसकी आवश्यकता है तो आप अलर्ट को कोशिश करने और पकड़ने के ब्लॉक के साथ रख सकते हैं।

+1

ओपी 'INotifyPropertyChanging' इंटरफ़ेस के बारे में पूछ रहा है, नहीं' INotifyPropertyChanged' –

+1

गलत इंटरफ़ेस की गलती जानबूझ कर अनदेखी करते हुए इस परिदृश्य में लॉग फाइल में जाने पर और कोशिश/संपत्ति सत्यापन के लिए न के बराबर अपवादों को पकड़ने नहीं बहुत अच्छा सलाह है। – JRoughan

1

INotifyPropertyChanging संपत्ति परिवर्तन से ठीक पहले लागू हो जाता है। महत्वपूर्ण क्यों? ताकि एक बाहरी घटना हैंडलर अपवाद फेंक सके और परिवर्तन को रोक सके। और आप ऐसा क्यों करना चाहते हैं? किसी दिन यह किसी और के कोड बेस में बग के लिए आपका एकमात्र कामकाज हो सकता है, इसलिए बचने के लिए बहुत जल्दी न हो।

+5

इवेंट फ़ायरर के निष्पादन को समाप्त करने के लिए किसी इवेंट हैंडलर में अपवाद फेंकने से मुझे यह करने के विकल्प सहित एक विशाल कोड गंध के रूप में हमला करता है * बस मामले में * मुझे और भी बदतर बना देता है। –

3

INotifyPropertyChanging लिंक से SQL के उपयोग के लिए एक अनुकूलन है। जब कोई ऑब्जेक्ट इस इंटरफ़ेस को लागू करता है, तो यह बदलते ईवेंट का उपयोग करता है क्योंकि सिग्नल के पुराने मूल्य को कैश करने के लिए सिग्नल होता है। यदि ऑब्जेक्ट इस इंटरफ़ेस को लागू नहीं करता है, तो यह हमेशा स्मृति मान को बढ़ाएगा, स्मृति उपयोग को बढ़ाएगा। अधिक जानकारी के लिए How does INotifyPropertyChanging interface helps limit memory consumption देखें।

संबंधित मुद्दे