Implementing INotifyPropertyChanged - does a better way exist?

前端 未结 30 2632
感情败类
感情败类 2020-11-21 05:23

Microsoft should have implemented something snappy for INotifyPropertyChanged, like in the automatic properties, just specify {get; set; notify;} I

30条回答
  •  日久生厌
    2020-11-21 05:49

    I introduce a Bindable class in my blog at http://timoch.com/blog/2013/08/annoyed-with-inotifypropertychange/ Bindable uses a dictionary as a property bag. It's easy enough to add the necessary overloads for a subclass to manage its own backing field using ref parameters.

    • No magic string
    • No reflection
    • Can be improved to suppress the default dictionary lookup

    The code:

    public class Bindable : INotifyPropertyChanged {
        private Dictionary _properties = new Dictionary();
    
        /// 
        /// Gets the value of a property
        /// 
        /// 
        /// 
        /// 
        protected T Get([CallerMemberName] string name = null) {
            Debug.Assert(name != null, "name != null");
            object value = null;
            if (_properties.TryGetValue(name, out value))
                return value == null ? default(T) : (T)value;
            return default(T);
        }
    
        /// 
        /// Sets the value of a property
        /// 
        /// 
        /// 
        /// 
        /// Use this overload when implicitly naming the property
        protected void Set(T value, [CallerMemberName] string name = null) {
            Debug.Assert(name != null, "name != null");
            if (Equals(value, Get(name)))
                return;
            _properties[name] = value;
            OnPropertyChanged(name);
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    It can be used like this:

    public class Contact : Bindable {
        public string FirstName {
            get { return Get(); }
            set { Set(value); }
        }
    }
    

提交回复
热议问题