C# 6.0 mvvm automatically raise PropertyChanged event

In c#+xaml applications I offen had to write similar code when you want your ViewModel notify view about property changing:

private object _property;
public object Property
{
  get { return _property; }
  set
  {
    _property = value; 
    OnPropertyChanged();
  }
}

it's not hard to write thouse liens especially with resharper, but usually it makes your view model very long and less readable.
So I tried to find way to decrease amount of lines. 

After some experiments (post sharp, custom attributes, etc.) I came to following solution:

- created property wrapper class Prop<T> :

public class Prop<T> : INotifyPropertyChanged
    {
        private T _value;
        
        public Prop(Action propertyChangedCallback)
        {
            _propertyChangedCallback = propertyChangedCallback;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public T Value
        {
            get { return _value; }
            set
            {
                _value = value;
                OnPropertyChanged();
            }
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

And in base ViewModelBase class added method GetProp:

private Dictionary<string, object> _props;

private Dictionary<string, object> Props => _props ?? (_props = new Dictionary<string, object>()); 

protected Prop<T> GetProp<T>([CallerMemberName] string key = null)
{
            object result;
            if (!Props.TryGetValue(key, out result))
            {
                result = new Prop<T>(() => RaisePropertyChanged(key));
                Props[key] = result;
            }

            return (Prop<T>)result;
}

So now I can write only 1 line instead of 10:
public Prop<string> MyLittleProperty => GetProp<string>();
But there is a minus in this method: you can't using your property just by name like MyLittleProperty = value, but will have to write: MyLittleProperty.Value = newValue;
or you can extend your Prop class with method Set(value), which will be little shorter.
Also in Xaml you will erite {Binding MyLittleProperty.Value} otherwise you'll see ToString() result of Prop class (in case if you binding to textblock.text)

I belive there can be workaround by using TypeConvertor class, but I didn't try it in my current project. It's have to work on winrt 8.1 and there are no support for TypeConvertor. Only in windows 10 and classical Net Framework.

So If you'll find better solution, welcome to commentaries!

Add comment

Loading