/// <summary> /// RaiseAndSetIfChanged fully implements a Setter for a read-write /// property on a ReactiveObject, making the assumption that the /// property has a backing field named "_NameOfProperty". To change this /// assumption, set RxApp.GetFieldNameForPropertyNameFunc. /// </summary> /// <param name="property">An Expression representing the property (i.e. /// 'x => x.SomeProperty'</param> /// <param name="newValue">The new value to set the property to, almost /// always the 'value' keyword.</param> /// <returns>The newly set value, normally discarded.</returns> public static TRet RaiseAndSetIfChanged <TObj, TRet>( this TObj This, TRet newValue, [CallerMemberName] string propertyName = null ) where TObj : ReactiveObject { Contract.Requires(This != null); Contract.Requires(propertyName != null); var fi = Reflection.GetBackingFieldInfoForProperty <TObj>(propertyName); var field_val = fi.GetValue(This); if (EqualityComparer <TRet> .Default.Equals((TRet)field_val, (TRet)newValue)) { return(newValue); } This.raisePropertyChanging(propertyName); fi.SetValue(This, newValue); This.raisePropertyChanged(propertyName); return(newValue); }
/// <summary> /// RaiseAndSetIfChanged fully implements a Setter for a read-write /// property on a ReactiveObject, making the assumption that the /// property has a backing field named "_NameOfProperty". To change this /// assumption, set RxApp.GetFieldNameForPropertyNameFunc. /// </summary> /// <param name="property">An Expression representing the property (i.e. /// 'x => x.SomeProperty'</param> /// <param name="newValue">The new value to set the property to, almost /// always the 'value' keyword.</param> /// <returns>The newly set value, normally discarded.</returns> public static TRet RaiseAndSetIfChanged <TObj, TRet>( this TObj This, Expression <Func <TObj, TRet> > property, TRet newValue) where TObj : ReactiveObject { Contract.Requires(This != null); Contract.Requires(property != null); FieldInfo field; string prop_name = Reflection.SimpleExpressionToPropertyName(property); field = Reflection.GetBackingFieldInfoForProperty <TObj>(prop_name); var field_val = field.GetValue(This); if (EqualityComparer <TRet> .Default.Equals((TRet)field_val, (TRet)newValue)) { return(newValue); } This.raisePropertyChanging(prop_name); field.SetValue(This, newValue); This.raisePropertyChanged(prop_name); return(newValue); }
/// <summary> /// Converts an Observable to an ObservableAsPropertyHelper and /// automatically provides the onChanged method to raise the property /// changed notification. /// </summary> /// <param name="source">The ReactiveObject that has the property</param> /// <param name="property">An Expression representing the property (i.e. /// 'x => x.SomeProperty'</param> /// <param name="initialValue">The initial value of the property.</param> /// <param name="scheduler">The scheduler that the notifications will be /// provided on - this should normally be a Dispatcher-based scheduler /// (and is by default)</param> /// <returns>An initialized ObservableAsPropertyHelper; use this as the /// backing field for your property.</returns> public static ObservableAsPropertyHelper <TRet> ToProperty <TObj, TRet>( this IObservable <TRet> This, TObj source, Expression <Func <TObj, TRet> > property, TRet initialValue = default(TRet), IScheduler scheduler = null, bool setViaReflection = true) where TObj : ReactiveObject { var ret = source.ObservableToProperty(This, property, initialValue, scheduler); string propName = Reflection.SimpleExpressionToPropertyName(property); if (setViaReflection) { var fi = Reflection.GetBackingFieldInfoForProperty <TObj>(propName, true); if (fi != null) { fi.SetValue(source, ret); } } return(ret); }