/// <summary> /// Creates a special storage locaiton wrapped in a BindingValue, which supports change notification. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="initialValue">The initial value to which the storage location is initialized.</param> /// <param name="name"></param> /// <returns></returns> public static BindingValue <T> Variable <T>(T initialValue, string name = "?") { var storage = initialValue; BindingValue <T> bindingValue = null; Action <T> setter = v => { storage = v; bindingValue.NotifyChange(); }; Func <T> getter = () => storage; bindingValue = new BindingValue <T>(setter, getter, name); return(bindingValue); }
/// <summary> /// Creates a BindingValue from an expression that accesses a property or field. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr"></param> /// <param name="notifier"></param> /// <returns></returns> public static BindingValue <T> Member <T>(Expression <Func <T> > expr, INotifyPropertyChanged notifier = null) { var accessor = ReflectHelper.AnalyzeMember(expr); var instance = accessor.InstanceGetter(); var instanceName = ReflectHelper.TryGetName(instance); notifier = notifier ?? accessor.InstanceGetter() as INotifyPropertyChanged; var bindingValue = new BindingValue <T>(accessor.Setter, accessor.Getter, $"{instanceName ?? "?"}.{accessor.TopmostMember.Name}"); if (notifier != null) { notifier.PropertyChanged += (sender, e) => { if (e.PropertyName == accessor.TopmostMember.Name) { bindingValue.NotifyChange(); } }; } return(bindingValue); }