/// <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 = RxApp.simpleExpressionToPropertyName <TObj, TRet>(property); field = RxApp.getFieldInfoForProperty <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) where TObj : ReactiveObject { var ret = source.ObservableToProperty(This, property, initialValue, scheduler); string propName = RxApp.simpleExpressionToPropertyName(property); var fi = RxApp.getFieldInfoForProperty <TObj>(propName); fi.SetValue(source, ret); return(ret); }
/// <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) where TObj : ReactiveObject { var ret = source.ObservableToProperty(This, property, initialValue, scheduler); string propName = RxApp.simpleExpressionToPropertyName(property); // NB: Some people decided to name their backing field something // weird and use the return value of this method in RxUI 2. If they // did that, we'll just roll with it. var fi = RxApp.getFieldInfoForProperty <TObj>(propName, true); if (fi != null) { fi.SetValue(source, ret); } return(ret); }