diff --git a/src/ReactiveUI/PropertyBinding.cs b/src/ReactiveUI/PropertyBinding.cs index 67be00cb5..ff5f23c96 100755 --- a/src/ReactiveUI/PropertyBinding.cs +++ b/src/ReactiveUI/PropertyBinding.cs @@ -46,11 +46,19 @@ static BindingMixins() /// An object that can provide a hint for the converter. /// The semantics of this object is defined by the converter used. /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// + /// + /// An optional to use when converting from the + /// view to viewModel property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. /// - public static IReactiveBinding> Bind( + public static IReactiveBinding> Bind( this TView view, TViewModel viewModel, Expression> vmProperty, @@ -94,6 +102,18 @@ public static IReactiveBinding> Bind + /// + /// An object that can provide a hint for the converter. + /// The semantics of this object is defined by the converter used. + /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// + /// + /// An optional to use when converting from the + /// view to viewModel property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. @@ -165,6 +185,10 @@ public static IReactiveBinding> BindThe type of the view being bound. /// The type of the property bound on the view model. /// The type of the property bound on the view. + /// /// + /// A dummy type, only the fact that + /// emits values is considered, not the actual values emitted. + /// /// The instance of the view to bind. /// The instance of the view model to bind. /// @@ -236,6 +260,10 @@ public static IReactiveBinding> Bind + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. @@ -298,17 +326,27 @@ public static IReactiveBinding OneWayBind /// BindTo takes an Observable stream and applies it to a target - /// property. Conceptually it is similar to "Subscribe(x => - /// target.property = x)", but allows you to use child properties + /// property. Conceptually it is similar to Subscribe(x => + /// target.property = x), but allows you to use child properties /// without the null checks. /// + /// The source type. + /// The target object type. + /// The type of the property on the target object. + /// The observable stream to bind to a target property /// The target object whose property will be set. - /// An expression representing the target - /// property to set. This can be a child property (i.e. x.Foo.Bar.Baz). + /// + /// An expression representing the target property to set. + /// This can be a child property (i.e. x.Foo.Bar.Baz). + /// /// /// An object that can provide a hint for the converter. /// The semantics of this object is defined by the converter used. /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// /// An object that when disposed, disconnects the binding. public static IDisposable BindTo( this IObservable This, @@ -364,6 +402,14 @@ public interface IPropertyBinderImplementation : IEnableLogger /// An object that can provide a hint for the converter. /// The semantics of this object is defined by the converter used. /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// + /// + /// An optional to use when converting from the + /// view to viewModel property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. @@ -464,11 +510,15 @@ IReactiveBinding> Bind + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. - /// - /// + /// + /// /// There is no registered converter from to . /// IReactiveBinding OneWayBind( @@ -523,13 +573,24 @@ IReactiveBinding OneWayBind /// BindTo takes an Observable stream and applies it to a target - /// property. Conceptually it is similar to "Subscribe(x => - /// target.property = x)", but allows you to use child properties + /// property. Conceptually it is similar to Subscribe(x => + /// target.property = x), but allows you to use child properties /// without the null checks. /// + /// The target observable to bind to. /// The target object whose property will be set. - /// An expression representing the target - /// property to set. This can be a child property (i.e. x.Foo.Bar.Baz). + /// + /// An expression representing the target property to set. + /// This can be a child property (i.e. x.Foo.Bar.Baz). + /// + /// + /// An object that can provide a hint for the converter. + /// The semantics of this object is defined by the converter used. + /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// /// An object that when disposed, disconnects the binding. IDisposable BindTo( IObservable This, @@ -539,7 +600,10 @@ IDisposable BindTo( IBindingTypeConverter vmToViewConverterOverride = null); } - public class PropertyBinderImplementation : IPropertyBinderImplementation + /// + /// Provides methods to bind properties to observables. + /// + public class PropertyBinderImplementation : IPropertyBinderImplementation { /// /// Creates a two-way binding between a view model and a view. @@ -571,7 +635,7 @@ public class PropertyBinderImplementation : IPropertyBinderImplementation /// /// If it is left null, the framework will attempt to automagically figure out /// the control and property that is to be bound, by looking for a control of the - /// same name as the , and its most natural property. + /// same name as the , and its most natural property. /// /// /// An observable, that when signaled, indicates that the view property @@ -582,6 +646,14 @@ public class PropertyBinderImplementation : IPropertyBinderImplementation /// An object that can provide a hint for the converter. /// The semantics of this object is defined by the converter used. /// + /// + /// An optional to use when converting from the + /// viewModel to view property. + /// + /// + /// An optional to use when converting from the + /// view to viewModel property. + /// /// /// An instance of that, when disposed, /// disconnects the binding. @@ -598,12 +670,12 @@ public IReactiveBinding> Bind vmToViewFunc = (TVMProp vmValue, out TVProp vValue) => { @@ -639,7 +711,7 @@ public IReactiveBinding> BindThe instance of the view model to bind. /// /// An expression indicating the property that is bound on the view model. - /// This can be a chain of properties of the form vm => vm.Foo.Bar.Baz + /// This can be a chain of properties of the form vm => vm.Foo.Bar.Baz /// and the binder will attempt to subscribe to changes on each recursively. /// /// @@ -715,9 +787,9 @@ IReactiveBinding> bindImpl true), signalInitialUpdate.Select(_ => true), - signalViewUpdate != null ? - signalViewUpdate.Select(_ => false) : - view.WhenAnyDynamic(viewExpression, x => (TVProp) x.Value).Select(_ => false)); + signalViewUpdate != null ? + signalViewUpdate.Select(_ => false) : + view.WhenAnyDynamic(viewExpression, x => (TVProp)x.Value).Select(_ => false)); var changeWithValues = somethingChanged.Select(isVm => { TVMProp vmValue; TVProp vValue; @@ -760,7 +832,7 @@ IReactiveBinding> bindImpl>(view, viewModel, viewExpression, vmExpression, + return new ReactiveBinding>(view, viewModel, viewExpression, vmExpression, changes, BindingDirection.TwoWay, disp); } @@ -790,17 +862,21 @@ IReactiveBinding> bindImpl, and its most natural property. + /// same name as the , and its most natural property. /// /// /// An object that can provide a hint for the converter. /// The semantics of this object is defined by the converter used. /// + /// + /// Delegate to convert the value of the view model's property's type to a value of the + /// view's property's type. + /// /// /// An instance of that, when disposed, /// disconnects the binding. /// - /// + /// /// There is no registered converter from to . /// public IReactiveBinding OneWayBind( @@ -818,8 +894,7 @@ public IReactiveBinding OneWayBind OneWayBind, and its most natural property. + /// same name as the , and its most natural property. /// /// /// A function that will be used to transform the values of the property on the view model @@ -896,20 +971,27 @@ public IReactiveBinding OneWayBind /// BindTo takes an Observable stream and applies it to a target - /// property. Conceptually it is similar to "Subscribe(x => - /// target.property = x)", but allows you to use child properties + /// property. Conceptually it is similar to Subscribe(x => + /// target.property = x), but allows you to use child properties /// without the null checks. /// + /// The source type. + /// The target object type. + /// The type of the property on the target object. /// The target object whose property will be set. - /// An expression representing the target - /// property to set. This can be a child property (i.e. x.Foo.Bar.Baz). + /// + /// An expression representing the target property to set. + /// This can be a child property (i.e. x.Foo.Bar.Baz). + /// The observable to apply to the target property. + /// + /// An object that can provide a hint for the converter. + /// The semantics of this object is defined by the converter used. + /// + /// + /// Delegate to convert the value of the view model's property's type to a value of the + /// view's property's type. + /// /// An object that when disposed, disconnects the binding. - /// This. - /// Conversion hint. - /// Vm to view converter override. - /// The 1st type parameter. - /// The 2nd type parameter. - /// The 3rd type parameter. public IDisposable BindTo( IObservable This, TTarget target, @@ -926,11 +1008,11 @@ public IDisposable BindTo( var ret = evalBindingHooks(This, target, null, viewExpression, BindingDirection.OneWay); if (!ret) return Disposable.Empty; - - var converter = vmToViewConverterOverride ?? getConverterForTypes(typeof (TValue), typeof(TTValue)); + + var converter = vmToViewConverterOverride ?? getConverterForTypes(typeof(TValue), typeof(TTValue)); if (converter == null) { - throw new ArgumentException(String.Format("Can't convert {0} to {1}. To fix this, register a IBindingTypeConverter", typeof (TValue), typeof(TTValue))); + throw new ArgumentException(String.Format("Can't convert {0} to {1}. To fix this, register a IBindingTypeConverter", typeof(TValue), typeof(TTValue))); } var source = This.SelectMany(x => { @@ -948,7 +1030,7 @@ IDisposable bindToDirect( Expression viewExpression) { var setter = Reflection.GetValueSetterOrThrow(viewExpression.GetMemberInfo()); - if (viewExpression.GetParent().NodeType == ExpressionType.Parameter) { + if (viewExpression.GetParent().NodeType == ExpressionType.Parameter) { return This.Subscribe( x => setter(target, x, viewExpression.GetArgumentsArray()), ex => { @@ -983,12 +1065,12 @@ bool evalBindingHooks(TViewModel viewModel, TView view, Expre }; } else { vmFetcher = () => { - return new[] { + return new[] { new ObservedChange(null, null, viewModel) }; }; } - + var vFetcher = new Func[]>(() => { IObservedChange[] fetchedValues; Reflection.TryGetAllValuesForPropertyChain(out fetchedValues, view, viewExpression.GetExpressionChain()); @@ -999,8 +1081,8 @@ bool evalBindingHooks(TViewModel viewModel, TView view, Expre acc && x.ExecuteHook(viewModel, view, vmFetcher, vFetcher, direction)); if (!shouldBind) { - var vmString = String.Format("{0}.{1}", typeof (TViewModel).Name, String.Join(".", vmExpression)); - var vString = String.Format("{0}.{1}", typeof (TView).Name, String.Join(".", viewExpression)); + var vmString = String.Format("{0}.{1}", typeof(TViewModel).Name, String.Join(".", vmExpression)); + var vString = String.Format("{0}.{1}", typeof(TView).Name, String.Join(".", viewExpression)); this.Log().Warn("Binding hook asked to disable binding {0} => {1}", vmString, vString); } @@ -1010,8 +1092,7 @@ bool evalBindingHooks(TViewModel viewModel, TView view, Expre MemoizingMRUCache, IBindingTypeConverter> typeConverterCache = new MemoizingMRUCache, IBindingTypeConverter>( (types, _) => { return Locator.Current.GetServices() - .Aggregate(Tuple.Create(-1, default(IBindingTypeConverter)), (acc, x) => - { + .Aggregate(Tuple.Create(-1, default(IBindingTypeConverter)), (acc, x) => { var score = x.GetAffinityForObjects(types.Item1, types.Item2); return score > acc.Item1 && score > 0 ? Tuple.Create(score, x) : acc;