public ExpressionObserver CreateExpressionObserver( IObservablePropertyBag instance, PerspexProperty property) { IObservable<object> dataContext = null; if (property != Control.DataContextProperty) { dataContext = instance.GetObservable(Control.DataContextProperty); } else { var parent = instance.InheritanceParent as IObservablePropertyBag; if (parent != null) { dataContext = parent.GetObservable(Control.DataContextProperty); } } if (dataContext != null) { var result = new ExpressionObserver(null, SourcePropertyPath); dataContext.Subscribe(x => result.Root = x); return result; } return null; }
internal void Bind(IObservablePropertyBag target, PerspexProperty property, ISubject<object> subject) { var mode = BindingMode == BindingMode.Default ? property.DefaultBindingMode : BindingMode; switch (mode) { case BindingMode.Default: case BindingMode.OneWay: target.Bind(property, subject); break; case BindingMode.TwoWay: target.BindTwoWay(property, subject); break; case BindingMode.OneTime: target.GetObservable(Control.DataContextProperty).Subscribe(dataContext => { subject.Take(1).Subscribe(x => target.SetValue(property, x)); }); break; case BindingMode.OneWayToSource: target.GetObservable(property).Subscribe(subject); break; } }
/// <summary> /// Creates a subject that can be used to get and set the value of the binding. /// </summary> /// <param name="target">The target instance.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="targetIsDataContext"> /// Whether the target property is the DataContext property. /// </param> /// <returns>An <see cref="ISubject{object}"/>.</returns> public ISubject<object> CreateSubject( IObservablePropertyBag target, Type targetType, bool targetIsDataContext = false) { ExpressionObserver observer; if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextExpressionSubject(target, targetIsDataContext); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentExpressionSubject(target); } else { throw new NotSupportedException(); } return new ExpressionSubject( observer, targetType, Converter ?? DefaultValueConverter.Instance); }
public void Bind(IObservablePropertyBag instance, PerspexProperty property) { var subject = CreateSubject(instance, property); if (subject != null) { Bind(instance, property, subject); } }
public void Bind(IObservablePropertyBag instance, PerspexProperty property) { var subject = new ExpressionSubject(CreateExpressionObserver(instance, property)); if (subject != null) { Bind(instance, property, subject); } }
/// <summary> /// Applies the binding to a property on an instance. /// </summary> /// <param name="instance">The target instance.</param> /// <param name="property">The target property.</param> public void Bind(IObservablePropertyBag instance, PerspexProperty property) { var subject = CreateSubject( instance, property.PropertyType, property == Control.DataContextProperty); if (subject != null) { Bind(instance, property, subject); } }
/// <summary> /// Applies the binding to a property on an instance. /// </summary> /// <param name="instance">The target instance.</param> /// <param name="property">The target property.</param> public void Bind(IObservablePropertyBag instance, PerspexProperty property) { Contract.Requires<ArgumentNullException>(instance != null); Contract.Requires<ArgumentNullException>(property != null); var subject = CreateSubject( instance, property.PropertyType, property == Control.DataContextProperty); if (subject != null) { Bind(instance, property, subject); } }
public ISubject<object> CreateSubject( IObservablePropertyBag instance, PerspexProperty property) { if (Converter == null) { throw new NotSupportedException("MultiBinding without Converter not currently supported."); } var result = new Subject<object>(); var children = Bindings.Select(x => x.CreateExpressionSubject(instance, property)); var input = Observable.CombineLatest(children).Select(x => Converter.Convert(x, property.PropertyType, null, CultureInfo.CurrentUICulture)); input.Subscribe(result); return result; }
public ISubject <object> CreateSubject( IObservablePropertyBag instance, PerspexProperty property) { if (Converter == null) { throw new NotSupportedException("MultiBinding without Converter not currently supported."); } var result = new Subject <object>(); var children = Bindings.Select(x => x.CreateExpressionSubject(instance, property)); var input = Observable.CombineLatest(children).Select(x => Converter.Convert(x, property.PropertyType, null, CultureInfo.CurrentUICulture)); input.Subscribe(result); return(result); }
private ExpressionObserver CreateTemplatedParentSubject( IObservablePropertyBag target, string path) { Contract.Requires <ArgumentNullException>(target != null); var update = target.GetObservable(Control.TemplatedParentProperty) .Skip(1) .Select(_ => Unit.Default); var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), path, update); return(result); }
/// <summary> /// Creates a subject that can be used to get and set the value of the binding. /// </summary> /// <param name="target">The target instance.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="targetIsDataContext"> /// Whether the target property is the DataContext property. /// </param> /// <returns>An <see cref="ISubject{object}"/>.</returns> public ISubject<object> CreateSubject( IObservablePropertyBag target, Type targetType, bool targetIsDataContext = false) { if (Converter == null) { throw new NotSupportedException("MultiBinding without Converter not currently supported."); } var result = new BehaviorSubject<object>(PerspexProperty.UnsetValue); var children = Bindings.Select(x => x.CreateSubject(target, typeof(object))); var input = Observable.CombineLatest(children).Select(x => Converter.Convert(x, targetType, null, CultureInfo.CurrentUICulture)); input.Subscribe(result); return result; }
/// <summary> /// Creates a subject that can be used to get and set the value of the binding. /// </summary> /// <param name="target">The target instance.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="targetIsDataContext"> /// Whether the target property is the DataContext property. /// </param> /// <returns>An <see cref="ISubject{object}"/>.</returns> public ISubject <object> CreateSubject( IObservablePropertyBag target, Type targetType, bool targetIsDataContext = false) { Contract.Requires <ArgumentNullException>(target != null); Contract.Requires <ArgumentNullException>(targetType != null); var pathInfo = ParsePath(Path); ValidateState(pathInfo); ExpressionObserver observer; if (pathInfo.ElementName != null || ElementName != null) { observer = CreateElementSubject( (IControl)target, pathInfo.ElementName ?? ElementName, pathInfo.Path); } else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextSubject( target, pathInfo.Path, targetIsDataContext); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentSubject( target, pathInfo.Path); } else { throw new NotSupportedException(); } return(new ExpressionSubject( observer, targetType, Converter ?? DefaultValueConverter.Instance, ConverterParameter)); }
private ExpressionObserver CreateTemplatedParentExpressionSubject(IObservablePropertyBag target) { var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), GetExpression()); if (target.GetValue(Control.TemplatedParentProperty) == null) { // TemplatedParent should only be set once, so only listen for the first non-null // value. target.GetObservable(Control.TemplatedParentProperty) .Where(x => x != null) .Take(1) .Subscribe(x => result.UpdateRoot()); } return(result); }
/// <summary> /// Creates a subject that can be used to get and set the value of the binding. /// </summary> /// <param name="target">The target instance.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="targetIsDataContext"> /// Whether the target property is the DataContext property. /// </param> /// <returns>An <see cref="ISubject{object}"/>.</returns> public ISubject <object> CreateSubject( IObservablePropertyBag target, Type targetType, bool targetIsDataContext = false) { if (Converter == null) { throw new NotSupportedException("MultiBinding without Converter not currently supported."); } var result = new BehaviorSubject <object>(PerspexProperty.UnsetValue); var children = Bindings.Select(x => x.CreateSubject(target, typeof(object))); var input = Observable.CombineLatest(children).Select(x => Converter.Convert(x, targetType, null, CultureInfo.CurrentUICulture)); input.Subscribe(result); return(result); }
/// <summary> /// Creates a subject that can be used to get and set the value of the binding. /// </summary> /// <param name="target">The target instance.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="targetIsDataContext"> /// Whether the target property is the DataContext property. /// </param> /// <returns>An <see cref="ISubject{object}"/>.</returns> public ISubject<object> CreateSubject( IObservablePropertyBag target, Type targetType, bool targetIsDataContext = false) { Contract.Requires<ArgumentNullException>(target != null); Contract.Requires<ArgumentNullException>(targetType != null); var pathInfo = ParsePath(Path); ValidateState(pathInfo); ExpressionObserver observer; if (pathInfo.ElementName != null || ElementName != null) { observer = CreateElementSubject( (IControl)target, pathInfo.ElementName ?? ElementName, pathInfo.Path); } else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextSubject( target, pathInfo.Path, targetIsDataContext); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentSubject( target, pathInfo.Path); } else { throw new NotSupportedException(); } return new ExpressionSubject( observer, targetType, Converter ?? DefaultValueConverter.Instance, ConverterParameter); }
public ExpressionObserver CreateExpressionObserver( IObservablePropertyBag instance, PerspexProperty property) { var dataContextHost = property != Control.DataContextProperty ? instance : instance.InheritanceParent as IObservablePropertyBag; if (dataContextHost != null) { var result = new ExpressionObserver( () => dataContextHost.GetValue(Control.DataContextProperty), SourcePropertyPath); dataContextHost.GetObservable(Control.DataContextProperty).Subscribe(x => result.UpdateRoot()); return(result); } return(null); }
private ExpressionObserver CreateDataContextExpressionSubject( IObservablePropertyBag target, bool targetIsDataContext) { var dataContextHost = targetIsDataContext ? target.InheritanceParent as IObservablePropertyBag : target; if (dataContextHost != null) { var result = new ExpressionObserver( () => dataContextHost.GetValue(Control.DataContextProperty), GetExpression()); dataContextHost.GetObservable(Control.DataContextProperty).Subscribe(x => result.UpdateRoot()); return(result); } else { throw new InvalidOperationException( "Cannot bind to DataContext of object with no parent."); } }
private ExpressionObserver CreateTemplatedParentSubject( IObservablePropertyBag target, string path) { Contract.Requires <ArgumentNullException>(target != null); var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), path); if (target.GetValue(Control.TemplatedParentProperty) == null) { // TemplatedParent should only be set once, so only listen for the first non-null // value. target.GetObservable(Control.TemplatedParentProperty) .Where(x => x != null) .Take(1) .Subscribe(x => result.UpdateRoot()); } return(result); }
public ISubject <object> CreateExpressionSubject( IObservablePropertyBag instance, PerspexProperty property) { ExpressionObserver observer; if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextExpressionSubject(instance, property); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentExpressionSubject(instance, property); } else { throw new NotSupportedException(); } return(new ExpressionSubject( observer, property.PropertyType, Converter ?? DefaultValueConverter.Instance)); }
public ISubject<object> CreateExpressionSubject( IObservablePropertyBag instance, PerspexProperty property) { ExpressionObserver observer; if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextExpressionSubject(instance, property); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentExpressionSubject(instance, property); } else { throw new NotSupportedException(); } return new ExpressionSubject( observer, property.PropertyType, Converter ?? DefaultValueConverter.Instance); }
internal void Bind(IObservablePropertyBag target, PerspexProperty property, ISubject<object> subject) { var mode = Mode == BindingMode.Default ? property.DefaultBindingMode : Mode; switch (mode) { case BindingMode.Default: case BindingMode.OneWay: target.Bind(property, subject, Priority); break; case BindingMode.TwoWay: throw new NotSupportedException("TwoWay MultiBinding not currently supported."); case BindingMode.OneTime: target.GetObservable(Control.DataContextProperty).Subscribe(dataContext => { subject.Take(1).Subscribe(x => target.SetValue(property, x, Priority)); }); break; case BindingMode.OneWayToSource: target.GetObservable(property).Subscribe(subject); break; } }
private ExpressionObserver CreateTemplatedParentExpressionSubject(IObservablePropertyBag target) { var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), GetExpression()); if (target.GetValue(Control.TemplatedParentProperty) == null) { // TemplatedParent should only be set once, so only listen for the first non-null // value. target.GetObservable(Control.TemplatedParentProperty) .Where(x => x != null) .Take(1) .Subscribe(x => result.UpdateRoot()); } return result; }
private ExpressionObserver CreateTemplatedParentSubject( IObservablePropertyBag target, string path) { Contract.Requires<ArgumentNullException>(target != null); var update = target.GetObservable(Control.TemplatedParentProperty) .Skip(1) .Select(_ => Unit.Default); var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), path, update); return result; }
public ExpressionObserver CreateDataContextExpressionSubject( IObservablePropertyBag instance, PerspexProperty property) { var dataContextHost = property != Control.DataContextProperty ? instance : instance.InheritanceParent as IObservablePropertyBag; if (dataContextHost != null) { var result = new ExpressionObserver( () => dataContextHost.GetValue(Control.DataContextProperty), GetExpression()); dataContextHost.GetObservable(Control.DataContextProperty).Subscribe(x => result.UpdateRoot()); return result; } return null; }
/// <summary> /// Applies a binding subject to a property on an instance. /// </summary> /// <param name="target">The target instance.</param> /// <param name="property">The target property.</param> /// <param name="subject">The binding subject.</param> internal void Bind(IObservablePropertyBag target, PerspexProperty property, ISubject<object> subject) { Contract.Requires<ArgumentNullException>(target != null); Contract.Requires<ArgumentNullException>(property != null); Contract.Requires<ArgumentNullException>(subject != null); var mode = Mode == BindingMode.Default ? property.DefaultBindingMode : Mode; switch (mode) { case BindingMode.Default: case BindingMode.OneWay: target.Bind(property, subject, Priority); break; case BindingMode.TwoWay: target.BindTwoWay(property, subject, Priority); break; case BindingMode.OneTime: target.GetObservable(Control.DataContextProperty).Subscribe(dataContext => { subject.Take(1).Subscribe(x => target.SetValue(property, x, Priority)); }); break; case BindingMode.OneWayToSource: target.GetObservable(property).Subscribe(subject); break; } }
private ExpressionObserver CreateDataContextSubject( IObservablePropertyBag target, string path, bool targetIsDataContext) { Contract.Requires<ArgumentNullException>(target != null); if (!targetIsDataContext) { var result = new ExpressionObserver( () => target.GetValue(Control.DataContextProperty), path); /// TODO: Instead of doing this, make the ExpressionObserver accept an "update" /// observable as doing it this way can will cause a leak in Binding as this /// observable is never unsubscribed. target.GetObservable(Control.DataContextProperty).Subscribe(x => result.UpdateRoot()); return result; } else { return new ExpressionObserver( target.GetObservable(Visual.VisualParentProperty) .OfType<IObservablePropertyBag>() .Select(x => x.GetObservable(Control.DataContextProperty)) .Switch(), path); } }
private ExpressionObserver CreateDataContextExpressionSubject( IObservablePropertyBag target, bool targetIsDataContext) { var dataContextHost = targetIsDataContext ? target.InheritanceParent as IObservablePropertyBag : target; if (dataContextHost != null) { var result = new ExpressionObserver( () => dataContextHost.GetValue(Control.DataContextProperty), GetExpression()); dataContextHost.GetObservable(Control.DataContextProperty).Subscribe(x => result.UpdateRoot()); return result; } else { throw new InvalidOperationException( "Cannot bind to DataContext of object with no parent."); } }
private ExpressionObserver CreateTemplatedParentSubject( IObservablePropertyBag target, string path) { Contract.Requires<ArgumentNullException>(target != null); var result = new ExpressionObserver( () => target.GetValue(Control.TemplatedParentProperty), path); if (target.GetValue(Control.TemplatedParentProperty) == null) { // TemplatedParent should only be set once, so only listen for the first non-null // value. target.GetObservable(Control.TemplatedParentProperty) .Where(x => x != null) .Take(1) .Subscribe(x => result.UpdateRoot()); } return result; }
private ExpressionObserver CreateDataContextSubject( IObservablePropertyBag target, string path, bool targetIsDataContext) { Contract.Requires<ArgumentNullException>(target != null); if (!targetIsDataContext) { var update = target.GetObservable(Control.DataContextProperty) .Skip(1) .Select(_ => Unit.Default); var result = new ExpressionObserver( () => target.GetValue(Control.DataContextProperty), path, update); return result; } else { return new ExpressionObserver( target.GetObservable(Visual.VisualParentProperty) .OfType<IObservablePropertyBag>() .Select(x => x.GetObservable(Control.DataContextProperty)) .Switch(), path); } }