How to Raise Property Changed in Derived Classes?

前端 未结 1 845
夕颜
夕颜 2021-01-15 18:20

How do I raise PropertyChanged for SomeProperty in class B?

This example does not compile since PropertyChanged i

相关标签:
1条回答
  • 2021-01-15 18:43

    Solution 1:

    You can use this RaisePropertyChangedExtension:

    public static class RaisePropertyChangedExtension
    {
        public static void RaisePropertyChanged(this INotifyPropertyChanged @this, [CallerMemberName] string propertyName = null)
        {
            var declaringType = @this.GetType().GetEvent(nameof(INotifyPropertyChanged.PropertyChanged)).DeclaringType;
            var propertyChangedFieldInfo = declaringType.GetField(nameof(INotifyPropertyChanged.PropertyChanged), BindingFlags.Instance | BindingFlags.NonPublic);
            var propertyChangedEventHandler = propertyChangedFieldInfo.GetValue(@this) as PropertyChangedEventHandler;
            propertyChangedEventHandler?.Invoke(@this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Like this:

    public class B : A
    {
        private object _someProperty;
    
        public object SomeProperty
        {
            get => _someProperty;
            set
            {
                _someProperty = value;
                this.RaisePropertyChanged();
            }
        }
    }
    

    In my opinion this is the best solution I know so far.

    Disadvantage is that you're able to raise PropertyChanged from another class like this:

    public class C
    {
        public C(B b)
        {
            b.RaisePropertyChanged(nameof(b.SomeProperty));
        }
    }
    

    It's not good practise to raise PropertyChanged from other classes this way, so i'm not concerned by this disadvantage.

    This solution is inspired by Thomas Levesque's answer here: Simple small INotifyPropertyChanged implementation

    Solution 2:

    You can create a protected RaisePropertyChanged in the base class A:

    public class A : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    And call the method in the derived class B:

    public class B : A
    {
        private object _someProperty;
    
        public object SomeProperty
        {
            get => _someProperty;
            set
            {
                _someProperty = value;
                RaisePropertyChanged();
            }
        }
    }
    

    Disadvantage is that you have to implement the RaisePropertyChanged method for each new base class you're creating on the opposite you avoid the disadvantage that Solution 1 had.

    0 讨论(0)
提交回复
热议问题