/// <summary> /// Causes the change event of the binding to occur only when the <see cref="Control.LostFocus"/> event is triggered. /// </summary> /// <remarks> /// This is useful for text-based input controls such as the <see cref="NumericStepper"/> when a partial input can be invalid. /// The binding will only be updated when the control has lost the input focus, where by default it will be updated for every /// change while the user is updating the control. /// </remarks> /// <returns>A control binding that updates only when the control's input focus is lost.</returns> public static BindableBinding <T, TValue> WhenLostFocus <T, TValue>(this BindableBinding <T, TValue> binding) where T : Control { return(new BindableBinding <T, TValue>( binding.DataItem, c => binding.DataValue, (c, v) => binding.DataValue = v, addChangeEvent: (c, ev) => binding.DataItem.LostFocus += ev, removeChangeEvent: (c, ev) => binding.DataItem.LostFocus -= ev )); }
/// <summary> /// Binds to an object's <see cref="IBindable.DataContext"/> using the specified <paramref name="dataContextBinding"/>. /// </summary> /// <remarks> /// This creates a <see cref="DualBinding{TValue}"/> between a binding to the specified <paramref name="dataContextBinding"/> and this binding. /// Since the data context changes, the binding passed for the data context binding is an indirect binding, in that it is reused. /// The binding is added to the <see cref="IBindable.Bindings"/> collection. /// </remarks> /// <returns>A new dual binding that binds the <paramref name="dataContextBinding"/> to this control binding.</returns> /// <param name="dataContextBinding">Binding to get/set values from/to the control's data context.</param> /// <param name="mode">Dual binding mode.</param> /// <param name="defaultControlValue">Default control value.</param> /// <param name="defaultContextValue">Default context value.</param> public DualBinding <TValue> BindDataContext(IndirectBinding <TValue> dataContextBinding, DualBindingMode mode = DualBindingMode.TwoWay, TValue defaultControlValue = default(TValue), TValue defaultContextValue = default(TValue)) { var control = DataItem; if (control == null) { throw new InvalidOperationException("Binding must be attached to a control"); } var contextBinding = new BindableBinding <IBindable, object>(control, Binding.Delegate((IBindable w) => w.DataContext, null, (w, h) => w.DataContextChanged += h, (w, h) => w.DataContextChanged -= h)); var valueBinding = new ObjectBinding <object, TValue>(control.DataContext, dataContextBinding) { GettingNullValue = defaultControlValue, SettingNullValue = defaultContextValue, DataItem = contextBinding.DataValue }; DualBinding <TValue> binding = Bind(sourceBinding: valueBinding, mode: mode); contextBinding.DataValueChanged += delegate { ((ObjectBinding <object, TValue>)binding.Source).DataItem = contextBinding.DataValue; }; control.Bindings.Add(contextBinding); return(binding); }
/// <summary> /// Adds a new binding to the control with a direct value binding /// </summary> /// <param name="bindable">Bindable object to add the binding to</param> /// <param name="controlBinding">Binding to get/set the value from the control.</param> /// <param name="valueBinding">Value binding to get/set the value from another source.</param> /// <param name="mode">Mode of the binding</param> public static DualBinding <T> Bind <T>(this IBindable bindable, IndirectBinding <T> controlBinding, DirectBinding <T> valueBinding, DualBindingMode mode = DualBindingMode.TwoWay) { var binding = new BindableBinding <IBindable, T>(bindable, controlBinding); return(binding.Bind(sourceBinding: valueBinding, mode: mode)); }
/// <summary> /// Adds a new binding from the control to its data context /// </summary> /// <param name="bindable">Bindable object to add the binding to</param> /// <param name="controlBinding">Binding to get/set the value from the control.</param> /// <param name="dataContextBinding">Binding to get/set the value from the <see cref="IBindable.DataContext"/>.</param> /// <param name="mode">Mode of the binding.</param> /// <param name="defaultControlValue">Default control value to set to the objectValue, if the value of the control property is null.</param> /// <param name="defaultContextValue">Default context value to set to the control, if the objectValue or value of the objectBinding is null.</param> public static DualBinding <T> BindDataContext <T>(this IBindable bindable, IndirectBinding <T> controlBinding, IndirectBinding <T> dataContextBinding, DualBindingMode mode = DualBindingMode.TwoWay, T defaultControlValue = default(T), T defaultContextValue = default(T)) { var binding = new BindableBinding <IBindable, T>(bindable, controlBinding); return(binding.BindDataContext(dataContextBinding, mode, defaultControlValue, defaultContextValue)); }
/// <summary> /// Gets a binding that returns a <paramref name="defaultValue"/> if the specified <paramref name="binding"/> returns a null value. /// </summary> /// <returns>A new binding that returns a non-null value.</returns> /// <param name="binding">Source of the binding to get the value.</param> /// <param name="defaultValue">Default value to return instead of null.</param> /// <typeparam name="T">The type of the bindable object.</typeparam> /// <typeparam name="TValue">The value type.</typeparam> public static BindableBinding <T, TValue> DefaultIfNull <T, TValue>(this BindableBinding <T, TValue> binding, TValue defaultValue) where T : IBindable where TValue : class { return(binding.Convert(c => c ?? defaultValue, c => c)); }
/// <summary> /// Gets a binding that returns a <paramref name="defaultValue"/> if the specified <paramref name="binding"/> returns a null value. /// </summary> /// <returns>A new binding that returns a non-nullable value.</returns> /// <param name="binding">Source of the binding to get the value.</param> /// <param name="defaultValue">Default value, or null to use <c>default(TValue)</c>.</param> /// <typeparam name="T">The type of the bindable object.</typeparam> /// <typeparam name="TValue">The value type to convert from nullable to non-nullable.</typeparam> public static BindableBinding <T, TValue> DefaultIfNull <T, TValue>(this BindableBinding <T, TValue?> binding, TValue?defaultValue = null) where T : IBindable where TValue : struct { return(binding.Convert(c => c ?? defaultValue ?? default(TValue), c => c)); }
/// <summary> /// Gets a bindable binding with the inverse of the specified boolean value binding. /// </summary> /// <returns>A new binding to the inverse value.</returns> /// <param name="binding">Binding to invert.</param> /// <typeparam name="T">The type of the bindable object.</typeparam> public static BindableBinding <T, bool> Inverse <T>(this BindableBinding <T, bool> binding) where T : IBindable { return(binding.Convert(c => !c, c => !c)); }