Best way to notify property change when field is depending on another

后端 未结 3 1400
粉色の甜心
粉色の甜心 2021-01-31 06:16

What is the best way in c# to notify property changed on an item\'s field without set but get depends on other fields ?

For example :



        
3条回答
  •  不要未来只要你来
    2021-01-31 07:19

    Even though in this solution the event is still propagated from the setter (so not exactly what the question is about), it provides a nice, more manageable way for representing dependencies. Someone might find it useful.

    The solution is to create a custom wrapper for triggering INotifyPropertyChanged events. Instead of calling OnPropertyChanged manually we can define following mathods (preferably inside a base class that we will reuse later):

    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        internal void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        protected ViewModelPropertyChange SetPropertyValue(ref T property, T value, [CallerMemberName] string propertyName = null)
        {
            property = value;
            OnPropertyChanged(propertyName);
    
            return new ViewModelPropertyChange(this);
        }
    }
    

    This class provides us with a way of setting a value of a given field without a need for providing the name of a proparty the call comes from.

    We also have to define a class that will enable use to define dependent properties (instance of this class is returned from SetPropertyValue mathod).

    public class ViewModelPropertyChange
    {
        private readonly ViewModelBase _viewModel;
    
        public ViewModelPropertyChange(ViewModelBase viewModel)
        {
            _viewModel = viewModel;
        }
    
        public ViewModelPropertyChange WithDependent(string name)
        {
            _viewModel.OnPropertyChanged(name);
    
            return this;
        }
    }
    

    It simply stores a reference to an object that is being changed and makes it possible to propagate an event to next properties.

    With this we can create a class derived from ViewModelBase like this:

    class OurViewModel : ViewModelBase
    {
        private int _partOne;
        public int PartOne
        {
            get => _partOne;
            set => SetPropertyValue(ref _partOne, value)
                .WithDependent(nameof(Total));
        }
    
        private int _partTwo;
        public int PartTwo
        {
            get => _partTwo;
            set => SetPropertyValue(ref _partTwo, value)
                .WithDependent(nameof(Total))
                .WithDependent(nameof(PartTwoPlus2));
        }
    
        public int Total {
            get => PartOne + PartTwo;
        }
    
        public int PartTwoPlus2 {
            get => PartTwo + 2;
        }
    }
    

提交回复
热议问题