2012-09-17 25 views
9

में मैं जो पाठ बॉक्स नियंत्रण से विरासत में मिली है एक कस्टम नियंत्रण है। मैं अपने कस्टम नियंत्रण में INotifyPropertyChanged इंटरफ़ेस को कार्यान्वित करना चाहता हूं।INotifyPropertyChanged UserControl

public class CustomTextBox : TextBox, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 
} 

मेरी समस्या तब होती है जब मैं प्रॉपर्टी चेंजेड इवेंट हैंडलर हमेशा शून्य हो जाता हूं।

कोई भी मेरी मदद कर सकता है?

+0

यह आपके जैसा काम नहीं करता है। बस एक अतिरिक्त कक्षा बनाएं और वहां अधिसूचना इंटरफ़ेस लागू करें और इस कक्षा को UserControl के DataContext पर लागू करें। और यह आपकी तरह काम करेगा। –

उत्तर

12

प्रॉपर्टी चेंज इवेंट हैंडलर अलवास शून्य है।

यह तब तक सत्य रहेगा जब तक कि कुछ PropertyChanged ईवेंट की सदस्यता लेता है।

आमतौर पर, आप एक कस्टम नियंत्रण कर रहे हैं, हालांकि, आप INotifyPropertyChanged का उपयोग नहीं होता। इस परिदृश्य में, आप इसके बजाय Custom Dependency Property बनायेंगे। आम तौर पर, निर्भरता वस्तुओं (यानी: नियंत्रण) सभी का उपयोग करेगा निर्भरता गुण, और INPC वर्ग है जो इन वस्तुओं में से DataContext बन द्वारा प्रयोग किया जाता है। यह बाध्यकारी प्रणाली को ठीक से काम करने की अनुमति देता है।

6

आप क्या अपेक्षा की थी? प्रॉपर्टी चेंज इवेंट यूआई कोड द्वारा उपयोग किया जाता है, लेकिन उस अर्थ में आप लिख रहे हैं। नियंत्रण INPC (INotifyPropertyChanged का संक्षिप्त रूप) को लागू कभी नहीं, वे आपत्ति उठाने कि INPC को लागू किया है बाध्य कर रहे हैं। इस तरह कुछ यूआई गुण, उदा। टेक्स्ट टेक्स्टबॉक्स नियंत्रण पर संपत्ति ऐसी कक्षा पर एक संपत्ति के लिए बाध्य है। यह एमवीवीएम आर्किटेक्चर का आधार है।

उदाहरण के लिए, आप निम्नलिखित XAML कोड लिखना होगा:

<TextBlock x:Name="txtBox" Text="{Binding Title}" /> 

और तुम TextBlock के लिए डेटा संदर्भ निर्धारित (या अपने पूर्वजों के किसी भी, DataContext प्रचारित किया जाता है) निम्नलिखित तरीके से कोड में:

txtBox.DataContext = new Movie {Title = "Titanic"}; 

और अब वर्ग खुद के लिए:

public class Movie : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 

    private string _title; 
    public string Title 
    { 
     get { return _title; } 
     set 
     { 
      if (_title == value) return; 

      _title = value; 
      NotifyPropertyChanged("Title"); 
     } 
    } 
} 

अब, जब भी आप चर्चा शीर्षक संपत्ति को एंज करें, चाहे कोड में या अन्य बाध्यकारी के माध्यम से, यूआई स्वचालित रूप से रीफ्रेश हो जाएगा। डेटा बाध्यकारी और एमवीवीएम के लिए Google।

+2

जब भी डेटा बदलता है, यह नियंत्रण को अद्यतन कर रहा है, लेकिन मुझे लगता है कि ओपी दो-तरफा बाध्यकारी कार्यान्वित करने की कोशिश कर रहा है जहां डेटा स्रोत स्वचालित रूप से UserControl द्वारा अपडेट किया जाता है। संभावित रूप से यह सूचित करने का कोई तरीका है कि उपयोगकर्ता नियंत्रण ने संपत्ति को अद्यतन किया है, लेकिन मुझे अभी तक यह नहीं मिला है। – misnomer

1

कर जैसे मैं टिप्पणी में कहा। यह आपके जैसा काम नहीं करता है। बस एक अतिरिक्त कक्षा बनाएं और Notification Interface लागू करें और UserControl के DataContext पर इस कक्षा को लागू करें। और यह आपकी तरह काम करेगा।

public partial class W3 : UserControl 
    { 
     WeatherViewModel model = new WeatherViewModel(); 

     public W3() 
     { 
      InitializeComponent(); 
      this.DataContext = model; 
     } 

     public void UpdateUI(List<WeatherDetails> data, bool isNextDays) 
     { 
      model.UpdateUI(data, isNextDays); 
     } 
    } 

    class WeatherViewModel : INotifyPropertyChanged 
    {  

     public void UpdateUI(List<WeatherDetails> data, bool isNextDays) 
     { 
      List<WeatherDetails> weatherInfo = data; 
      if (weatherInfo.Count != 0) 
      { 
       CurrentWeather = weatherInfo.First(); 
       if (isNextDays) 
        Forecast = weatherInfo.Skip(1).ToList(); 
      } 
     } 

     private List<WeatherDetails> _forecast = new List<WeatherDetails>(); 

     public List<WeatherDetails> Forecast 
     { 
      get { return _forecast; } 
      set 
      { 
       _forecast = value; 
       OnPropertyChanged("Forecast"); 
      } 
     } 

     private WeatherDetails _currentWeather = new WeatherDetails(); 

     public WeatherDetails CurrentWeather 
     { 
      get { return _currentWeather; } 
      set 
      { 
       _currentWeather = value; 
       OnPropertyChanged("CurrentWeather"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void OnPropertyChanged(string propertyName) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    }