Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
 public XamlBindingDefinition(Control target, PerspexProperty targetProperty, PropertyPath sourcePropertyPath, BindingMode bindingMode)
 {
     this.target = target;
     this.targetProperty = targetProperty;
     this.sourcePropertyPath = sourcePropertyPath;
     this.bindingMode = bindingMode;
 }
Exemplo n.º 3
0
 public XamlBindingDefinition(Control target, PerspexProperty targetProperty, PropertyPath sourcePropertyPath, BindingMode bindingMode)
 {
     _target = target;
     _targetProperty = targetProperty;
     _sourcePropertyPath = sourcePropertyPath;
     _bindingMode = bindingMode;
 }
Exemplo n.º 4
0
        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;
            }
        }
Exemplo n.º 5
0
        public void Bind(IObservablePropertyBag instance, PerspexProperty property)
        {
            var subject = CreateSubject(instance, property);

            if (subject != null)
            {
                Bind(instance, property, subject);
            }
        }
Exemplo n.º 6
0
        public void Bind(IObservablePropertyBag instance, PerspexProperty property)
        {
            var subject = new ExpressionSubject(CreateExpressionObserver(instance, property));

            if (subject != null)
            {
                Bind(instance, property, subject);
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Merges the metadata with the base metadata.
 /// </summary>
 /// <param name="baseMetadata">The base metadata to merge.</param>
 /// <param name="property">The property to which the metadata is being applied.</param>
 public virtual void Merge(
     PropertyMetadata baseMetadata, 
     PerspexProperty property)
 {
     if (_defaultBindingMode == BindingMode.Default)
     {
         _defaultBindingMode = baseMetadata.DefaultBindingMode;
     }
 }
Exemplo n.º 8
0
        /// <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(IPerspexObject instance, PerspexProperty property)
        {
            var subject = CreateSubject(instance, property);

            if (subject != null)
            {
                Bind(instance, property, subject);
            }
        }
            public Accessor(PerspexObject instance, PerspexProperty property, Action<object> changed)
            {
                Contract.Requires<ArgumentNullException>(instance != null);
                Contract.Requires<ArgumentNullException>(property != null);

                _instance = instance;
                _property = property;
                _subscription = instance.GetObservable(property).Skip(1).Subscribe(changed);
            }
Exemplo n.º 10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PerspexPropertyValue"/> class.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="value">The current property value.</param>
 /// <param name="priority">The priority of the current value.</param>
 /// <param name="diagnostic">A diagnostic string.</param>
 public PerspexPropertyValue(
     PerspexProperty property,
     object value,
     BindingPriority priority,
     string diagnostic)
 {
     this.Property = property;
     this.Value = value;
     this.Priority = priority;
     this.Diagnostic = diagnostic;
 }
Exemplo n.º 11
0
        /// <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);
            }
        }
Exemplo n.º 12
0
 private static void SetBinding(
     object instance,
     MutableMember member, 
     PerspexProperty property, 
     IBinding binding)
 {
     if (!(AssignBinding(instance, member, binding) || ApplyBinding(instance, property, binding)))
     {
         throw new InvalidOperationException(
             $"Cannot assign to '{member.Name}' on '{instance.GetType()}");
     }
 }
Exemplo n.º 13
0
        public void GetDefaultValue_Returns_Registered_Value_For_Not_Overridden_Class()
        {
            PerspexProperty<string> target = new PerspexProperty<string>(
                "test",
                typeof(Class1),
                "Foo",
                false,
                BindingMode.OneWay,
                null);

            Assert.Equal("Foo", target.GetDefaultValue<Class2>());
        }
        public DataContextChangeSynchronizer(PerspexObject target, PerspexProperty targetProperty,
            PropertyPath sourcePropertyPath, object source, ITypeConverterProvider typeConverterProvider)
        {
            Guard.ThrowIfNull(target, nameof(target));
            Guard.ThrowIfNull(targetProperty, nameof(targetProperty));
            Guard.ThrowIfNull(sourcePropertyPath, nameof(sourcePropertyPath));
            Guard.ThrowIfNull(source, nameof(source));
            Guard.ThrowIfNull(typeConverterProvider, nameof(typeConverterProvider));

            this.bindingEndpoint = new TargetBindingEndpoint(target, targetProperty);
            this.sourceEndpoint = new ObservablePropertyBranch(source, sourcePropertyPath);
            this.targetPropertyTypeConverter = typeConverterProvider.GetTypeConverter(targetProperty.PropertyType);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PerspexPropertyChangedEventArgs"/> class.
 /// </summary>
 /// <param name="sender">The object that the property changed on.</param>
 /// <param name="property">The property that changed.</param>
 /// <param name="oldValue">The old value of the property.</param>
 /// <param name="newValue">The new value of the property.</param>
 /// <param name="priority">The priority of the binding that produced the value.</param>
 public PerspexPropertyChangedEventArgs(
     PerspexObject sender,
     PerspexProperty property,
     object oldValue,
     object newValue,
     BindingPriority priority)
 {
     this.Sender = sender;
     this.Property = property;
     this.OldValue = oldValue;
     this.NewValue = newValue;
     this.Priority = priority;
 }
Exemplo n.º 16
0
        /// <inheritdoc/>
        public InstancedBinding Initiate(
            IPerspexObject target,
            PerspexProperty targetProperty,
            object anchor = null)
        {
            Contract.Requires <ArgumentNullException>(target != null);

            var pathInfo = ParsePath(Path);

            ValidateState(pathInfo);

            ExpressionObserver observer;

            if (pathInfo.ElementName != null || ElementName != null)
            {
                observer = CreateElementObserver(
                    (target as IControl) ?? (anchor as IControl),
                    pathInfo.ElementName ?? ElementName,
                    pathInfo.Path);
            }
            else if (Source != null)
            {
                observer = CreateSourceObserver(Source, pathInfo.Path);
            }
            else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext)
            {
                observer = CreateDataContexObserver(
                    target,
                    pathInfo.Path,
                    targetProperty == Control.DataContextProperty,
                    anchor);
            }
            else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
            {
                observer = CreateTemplatedParentObserver(target, pathInfo.Path);
            }
            else
            {
                throw new NotSupportedException();
            }

            var subject = new ExpressionSubject(
                observer,
                targetProperty?.PropertyType ?? typeof(object),
                Converter ?? DefaultValueConverter.Instance,
                ConverterParameter,
                FallbackValue,
                Priority);

            return(new InstancedBinding(subject, Mode, Priority));
        }
Exemplo n.º 17
0
        /// <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="targetProperty">The target property.</param>
        /// <returns>An <see cref="ISubject{Object}"/>.</returns>
        public ISubject<object> CreateSubject(IPerspexObject target, PerspexProperty targetProperty)
        {
            if (Converter == null)
            {
                throw new NotSupportedException("MultiBinding without Converter not currently supported.");
            }

            var targetType = targetProperty?.PropertyType ?? typeof(object);
            var result = new BehaviorSubject<object>(PerspexProperty.UnsetValue);
            var children = Bindings.Select(x => x.CreateSubject(target, null));
            var input = children.CombineLatest().Select(x => ConvertValue(x, targetType));
            input.Subscribe(result);
            return result;
        }
Exemplo n.º 18
0
        public void Constructor_Sets_Properties()
        {
            PerspexProperty <string> target = new PerspexProperty <string>(
                "test",
                typeof(Class1),
                "Foo",
                false,
                BindingMode.OneWay);

            Assert.AreEqual("test", target.Name);
            Assert.AreEqual(typeof(string), target.PropertyType);
            Assert.AreEqual(typeof(Class1), target.OwnerType);
            Assert.AreEqual(false, target.Inherits);
        }
Exemplo n.º 19
0
 protected void AddPseudoClass(PerspexProperty <bool> property, string className)
 {
     this.GetObservable(property).Subscribe(x =>
     {
         if (x)
         {
             this.classes.Add(className);
         }
         else
         {
             this.classes.Remove(className);
         }
     });
 }
Exemplo n.º 20
0
        public void GetDefaultValue_Returns_Overridden_Value()
        {
            PerspexProperty <string> target = new PerspexProperty <string>(
                "test",
                typeof(Class1),
                "Foo",
                false,
                BindingMode.OneWay,
                null);

            target.OverrideDefaultValue(typeof(Class2), "Bar");

            Assert.Equal("Bar", target.GetDefaultValue <Class2>());
        }
Exemplo n.º 21
0
 private static void SetBinding(
     object instance,
     MutableMember member,
     PerspexProperty property,
     IValueContext context,
     IBinding binding)
 {
     if (!(AssignBinding(instance, member, binding) ||
           ApplyBinding(instance, property, context, binding)))
     {
         throw new InvalidOperationException(
                   $"Cannot assign to '{member.Name}' on '{instance.GetType()}");
     }
 }
Exemplo n.º 22
0
        public void GetDefaultValue_Returns_Overridden_Value()
        {
            PerspexProperty<string> target = new PerspexProperty<string>(
                "test",
                typeof(Class1),
                "Foo",
                false,
                BindingMode.OneWay,
                null);

            target.OverrideDefaultValue(typeof(Class2), "Bar");

            Assert.Equal("Bar", target.GetDefaultValue<Class2>());
        }
Exemplo n.º 23
0
        /// <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);
            }
        }
Exemplo n.º 24
0
        /// <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="targetProperty">The target property.</param>
        /// <returns>An <see cref="ISubject{Object}"/>.</returns>
        public ISubject <object> CreateSubject(IPerspexObject target, PerspexProperty targetProperty)
        {
            if (Converter == null)
            {
                throw new NotSupportedException("MultiBinding without Converter not currently supported.");
            }

            var targetType = targetProperty?.PropertyType ?? typeof(object);
            var result     = new BehaviorSubject <object>(PerspexProperty.UnsetValue);
            var children   = Bindings.Select(x => x.CreateSubject(target, null));
            var input      = children.CombineLatest().Select(x => ConvertValue(x, targetType));

            input.Subscribe(result);
            return(result);
        }
Exemplo n.º 25
0
        public void Constructor_Sets_Properties()
        {
            PerspexProperty<string> target = new PerspexProperty<string>(
                "test",
                typeof(Class1),
                "Foo",
                false,
                BindingMode.OneWay,
                null);

            Assert.Equal("test", target.Name);
            Assert.Equal(typeof(string), target.PropertyType);
            Assert.Equal(typeof(Class1), target.OwnerType);
            Assert.Equal(false, target.Inherits);
        }
Exemplo n.º 26
0
        /// <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);
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Applies an <see cref="InstancedBinding"/> a property on an <see cref="IPerspexObject"/>.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <param name="property">The property to bind.</param>
        /// <param name="binding">The instanced binding.</param>
        /// <param name="anchor">
        /// An optional anchor from which to locate required context. When binding to objects that
        /// are not in the logical tree, certain types of binding need an anchor into the tree in
        /// order to locate named controls or resources. The <paramref name="anchor"/> parameter
        /// can be used to provice this context.
        /// </param>
        /// <returns>An <see cref="IDisposable"/> which can be used to cancel the binding.</returns>
        public static IDisposable Apply(
            IPerspexObject target,
            PerspexProperty property,
            InstancedBinding binding,
            object anchor)
        {
            Contract.Requires <ArgumentNullException>(target != null);
            Contract.Requires <ArgumentNullException>(property != null);
            Contract.Requires <ArgumentNullException>(binding != null);

            var mode = binding.Mode;

            if (mode == BindingMode.Default)
            {
                mode = property.GetMetadata(target.GetType()).DefaultBindingMode;
            }

            switch (mode)
            {
            case BindingMode.Default:
            case BindingMode.OneWay:
                return(target.Bind(property, binding.Observable ?? binding.Subject, binding.Priority));

            case BindingMode.TwoWay:
                return(new CompositeDisposable(
                           target.Bind(property, binding.Subject, binding.Priority),
                           target.GetObservable(property).Subscribe(binding.Subject)));

            case BindingMode.OneTime:
                var source = binding.Subject ?? binding.Observable;

                if (source != null)
                {
                    return(source.Take(1).Subscribe(x => target.SetValue(property, x, binding.Priority)));
                }
                else
                {
                    target.SetValue(property, binding.Value, binding.Priority);
                    return(Disposable.Empty);
                }

            case BindingMode.OneWayToSource:
                return(target.GetObservable(property).Subscribe(binding.Subject));

            default:
                throw new ArgumentException("Invalid binding mode.");
            }
        }
Exemplo n.º 28
0
        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;
        }
Exemplo n.º 29
0
        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);
        }
Exemplo n.º 30
0
        /// <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="targetProperty">The target property. May be null.</param>
        /// <returns>An <see cref="ISubject{Object}"/>.</returns>
        public ISubject<object> CreateSubject(
            IPerspexObject target, 
            PerspexProperty targetProperty)
        {
            Contract.Requires<ArgumentNullException>(target != null);

            var pathInfo = ParsePath(Path);
            ValidateState(pathInfo);

            ExpressionObserver observer;

            if (pathInfo.ElementName != null || ElementName != null)
            {
                observer = CreateElementObserver(
                    (IControl)target, 
                    pathInfo.ElementName ?? ElementName, 
                    pathInfo.Path);
            }
            else if (Source != null)
            {
                observer = CreateSourceObserver(Source, pathInfo.Path);
            }
            else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext)
            {
                observer = CreateDataContexObserver(
                    target, 
                    pathInfo.Path,
                    targetProperty == Control.DataContextProperty);
            }
            else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
            {
                observer = CreateTemplatedParentObserver(target, pathInfo.Path);
            }
            else
            {
                throw new NotSupportedException();
            }

            return new ExpressionSubject(
                observer,
                targetProperty?.PropertyType ?? typeof(object),
                Converter ?? DefaultValueConverter.Instance,
                ConverterParameter,
                FallbackValue);
        }
Exemplo n.º 31
0
        public PropertyDetails(PerspexObject o, PerspexProperty property)
        {
            Name = property.IsAttached ?
                   $"[{property.OwnerType.Name}.{property.Name}]" :
                   property.Name;
            IsAttached = property.IsAttached;

            // TODO: Unsubscribe when view model is deactivated.
            o.GetObservable(property).Subscribe(x =>
            {
                var diagnostic = o.GetDiagnostic(property);
                Value          = diagnostic.Value ?? "(null)";
                Priority       = (diagnostic.Priority != BindingPriority.Unset) ?
                                 diagnostic.Priority.ToString() :
                                 diagnostic.Property.Inherits ? "Inherited" : "Unset";
                Diagnostic = diagnostic.Diagnostic;
            });
        }
Exemplo n.º 32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TreeItemContainerGenerator{T}"/> class.
        /// </summary>
        /// <param name="owner">The owner control.</param>
        /// <param name="contentProperty">The container's Content property.</param>
        /// <param name="itemsProperty">The container's Items property.</param>
        /// <param name="isExpandedProperty">The container's IsExpanded property.</param>
        /// <param name="rootGenerator">
        /// The item container for the root of the tree, or null if this generator is itself the
        /// root of the tree.
        /// </param>
        public TreeItemContainerGenerator(
            IControl owner,
            PerspexProperty contentProperty,
            PerspexProperty itemsProperty,
            PerspexProperty isExpandedProperty,
            ITreeItemContainerGenerator rootGenerator)
            : base(owner, contentProperty)
        {
            ItemsProperty      = itemsProperty;
            IsExpandedProperty = isExpandedProperty;
            RootGenerator      = rootGenerator;

            if (rootGenerator == null)
            {
                _itemToContainer = new Dictionary <object, T>();
                _containerToItem = new Dictionary <IControl, object>();
            }
        }
Exemplo n.º 33
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TreeItemContainerGenerator{T}"/> class.
        /// </summary>
        /// <param name="owner">The owner control.</param>
        /// <param name="contentProperty">The container's Content property.</param>
        /// <param name="itemsProperty">The container's Items property.</param>
        /// <param name="isExpandedProperty">The container's IsExpanded property.</param>
        /// <param name="index">The container index for the tree</param>
        public TreeItemContainerGenerator(
            IControl owner,
            PerspexProperty contentProperty,
            PerspexProperty itemsProperty,
            PerspexProperty isExpandedProperty,
            TreeContainerIndex index)
            : base(owner, contentProperty)
        {
            Contract.Requires <ArgumentNullException>(owner != null);
            Contract.Requires <ArgumentNullException>(contentProperty != null);
            Contract.Requires <ArgumentNullException>(itemsProperty != null);
            Contract.Requires <ArgumentNullException>(isExpandedProperty != null);
            Contract.Requires <ArgumentNullException>(index != null);

            ItemsProperty      = itemsProperty;
            IsExpandedProperty = isExpandedProperty;
            Index = index;
        }
Exemplo n.º 34
0
        public PropertyDetails(PerspexObject o, PerspexProperty property)
        {
            Name = property.IsAttached ?
                $"[{property.OwnerType.Name}.{property.Name}]" :
                property.Name;
            IsAttached = property.IsAttached;

            // TODO: Unsubscribe when view model is deactivated.
            o.GetObservable(property).Subscribe(x =>
            {
                var diagnostic = o.GetDiagnostic(property);
                Value = diagnostic.Value ?? "(null)";
                Priority = (diagnostic.Priority != BindingPriority.Unset) ?
                    diagnostic.Priority.ToString() :
                    diagnostic.Property.Inherits ? "Inherited" : "Unset";
                Diagnostic = diagnostic.Diagnostic;
            });
        }
Exemplo n.º 35
0
        private void Bind(
            IStyleable control,
            PerspexProperty property,
            IBinding binding,
            ISubject <object> subject)
        {
            var mode = binding.Mode;

            if (mode == BindingMode.Default)
            {
                mode = property.GetMetadata(control.GetType()).DefaultBindingMode;
            }

            control.Bind(
                property,
                subject,
                mode,
                binding.Priority);
        }
Exemplo n.º 36
0
        private static bool ApplyBinding(
            object instance,
            PerspexProperty property,
            IValueContext context,
            IBinding binding)
        {
            if (property == null)
            {
                return(false);
            }

            var control = instance as IControl;

            if (control != null)
            {
                DelayedBinding.Add(control, property, binding);
            }
            else
            {
                // The target is not a control, so we need to find an anchor that will let us look
                // up named controls and style resources. First look for the closest IControl in
                // the TopDownValueContext.
                object anchor = context.TopDownValueContext.StoredInstances
                                .Select(x => x.Instance)
                                .OfType <IControl>()
                                .LastOrDefault();

                // If a control was not found, then try to find the highest-level style as the XAML
                // file could be a XAML file containing only styles.
                if (anchor == null)
                {
                    anchor = context.TopDownValueContext.StoredInstances
                             .Select(x => x.Instance)
                             .OfType <IStyle>()
                             .FirstOrDefault();
                }

                ((IPerspexObject)instance).Bind(property, binding, anchor);
            }

            return(true);
        }
Exemplo n.º 37
0
        public ExpressionObserver CreateTemplatedParentExpressionSubject(
            IObservablePropertyBag instance,
            PerspexProperty property)
        {
            var result = new ExpressionObserver(
                () => instance.GetValue(Control.TemplatedParentProperty),
                GetExpression());

            if (instance.GetValue(Control.TemplatedParentProperty) == null)
            {
                // TemplatedParent should only be set once, so only listen for the first non-null
                // value.
                instance.GetObservable(Control.TemplatedParentProperty)
                .Where(x => x != null)
                .Take(1)
                .Subscribe(x => result.UpdateRoot());
            }

            return(result);
        }
Exemplo n.º 38
0
        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);
        }
Exemplo n.º 39
0
        /// <summary>
        /// Adds a delayed binding to a control.
        /// </summary>
        /// <param name="target">The control.</param>
        /// <param name="property">The property on the control to bind to.</param>
        /// <param name="binding">The binding.</param>
        public static void Add(IControl target, PerspexProperty property, IBinding binding)
        {
            if (target.IsInitialized)
            {
                target.Bind(property, binding);
            }
            else
            {
                List <Entry> bindings;

                if (!_entries.TryGetValue(target, out bindings))
                {
                    bindings = new List <Entry>();
                    _entries.Add(target, bindings);

                    // TODO: Make this a weak event listener.
                    target.Initialized += ApplyBindings;
                }

                bindings.Add(new Entry(binding, property));
            }
        }
Exemplo n.º 40
0
        /// <summary>
        /// Gets a diagnostic for a <see cref="PerspexProperty"/> on a <see cref="PerspexObject"/>.
        /// </summary>
        /// <param name="o">The object.</param>
        /// <param name="property">The property.</param>
        /// <returns>
        /// A <see cref="PerspexPropertyValue"/> that can be used to diagnose the state of the
        /// property on the object.
        /// </returns>
        public static PerspexPropertyValue GetDiagnostic(this PerspexObject o, PerspexProperty property)
        {
            var set = o.GetSetValues();

            PriorityValue value;

            if (set.TryGetValue(property, out value))
            {
                return new PerspexPropertyValue(
                    property,
                    value.Value,
                    (BindingPriority)value.ValuePriority,
                    value.GetDiagnostic());
            }
            else
            {
                return new PerspexPropertyValue(
                    property,
                    o.GetValue(property),
                    BindingPriority.Unset,
                    "Unset");
            }
        }
Exemplo n.º 41
0
        /// <summary>
        /// Gets a diagnostic for a <see cref="PerspexProperty"/> on a <see cref="PerspexObject"/>.
        /// </summary>
        /// <param name="o">The object.</param>
        /// <param name="property">The property.</param>
        /// <returns>
        /// A <see cref="PerspexPropertyValue"/> that can be used to diagnose the state of the
        /// property on the object.
        /// </returns>
        public static PerspexPropertyValue GetDiagnostic(this PerspexObject o, PerspexProperty property)
        {
            var set = o.GetSetValues();

            PriorityValue value;

            if (set.TryGetValue(property, out value))
            {
                return(new PerspexPropertyValue(
                           property,
                           o.GetValue(property),
                           (BindingPriority)value.ValuePriority,
                           value.GetDiagnostic()));
            }
            else
            {
                return(new PerspexPropertyValue(
                           property,
                           o.GetValue(property),
                           BindingPriority.Unset,
                           "Unset"));
            }
        }
Exemplo n.º 42
0
        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));
        }
Exemplo n.º 43
0
        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);
        }
Exemplo n.º 44
0
        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;
            }
        }
Exemplo n.º 45
0
 public IDisposable Bind <T>(PerspexProperty <T> property, IObservable <T> source, BindingPriority priority = BindingPriority.LocalValue)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 46
0
 public IDisposable Bind(PerspexProperty property, IObservable <object> source, BindingPriority priority)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 47
0
 public bool IsSet(PerspexProperty property)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 48
0
 public void SetValue <T>(PerspexProperty <T> property, T value, BindingPriority priority = BindingPriority.LocalValue)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 49
0
 public void SetValue(PerspexProperty property, object value, BindingPriority priority)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 50
0
 public T GetValue <T>(PerspexProperty <T> property)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 51
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PropertyTransition"/> class.
 /// </summary>
 /// <param name="property">The property to be animated/</param>
 /// <param name="duration">The duration of the animation.</param>
 /// <param name="easing">The easing function to use.</param>
 public PropertyTransition(PerspexProperty property, TimeSpan duration, IEasing easing)
 {
     Property = property;
     Duration = duration;
     Easing = easing;
 }
Exemplo n.º 52
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Setter"/> class.
 /// </summary>
 /// <param name="property">The property to set.</param>
 /// <param name="value">The property value.</param>
 public Setter(PerspexProperty property, object value)
 {
     Property = property;
     Value    = value;
 }
Exemplo n.º 53
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SelectableMixin"/> class.
        /// </summary>
        /// <typeparam name="TControl">The control type.</typeparam>
        /// <param name="content">The content property.</param>
        /// <param name="logicalChildrenSelector">
        /// Given an control of <typeparamref name="TControl"/> should return the control's
        /// logical children collection.
        /// </param>
        /// <param name="presenterName">
        /// The name of the content presenter in the control's template.
        /// </param>
        public static void Attach <TControl>(
            PerspexProperty content,
            Func <TControl, IPerspexList <ILogical> > logicalChildrenSelector,
            string presenterName = "PART_ContentPresenter")
            where TControl : TemplatedControl
        {
            Contract.Requires <ArgumentNullException>(content != null);
            Contract.Requires <ArgumentNullException>(logicalChildrenSelector != null);

            EventHandler <RoutedEventArgs> templateApplied = (s, ev) =>
            {
                var sender = s as TControl;

                if (sender != null)
                {
                    var e         = (TemplateAppliedEventArgs)ev;
                    var presenter = (IControl)e.NameScope.Find(presenterName);

                    if (presenter != null)
                    {
                        presenter.ApplyTemplate();

                        var logicalChildren = logicalChildrenSelector(sender);
                        var subscription    = presenter
                                              .GetObservableWithHistory(ContentPresenter.ChildProperty)
                                              .Subscribe(child => UpdateLogicalChild(
                                                             sender,
                                                             logicalChildren,
                                                             child.Item1,
                                                             child.Item2));

                        UpdateLogicalChild(
                            sender,
                            logicalChildren,
                            logicalChildren.FirstOrDefault(),
                            presenter.GetValue(ContentPresenter.ChildProperty));

                        subscriptions.Value.Add(sender, subscription);
                    }
                }
            };

            TemplatedControl.TemplateAppliedEvent.AddClassHandler(
                typeof(TControl),
                templateApplied,
                RoutingStrategies.Direct);

            content.Changed.Subscribe(e =>
            {
                var sender = e.Sender as TControl;

                if (sender != null)
                {
                    var logicalChildren = logicalChildrenSelector(sender);
                    UpdateLogicalChild(sender, logicalChildren, e.OldValue, e.NewValue);
                }
            });

            Control.TemplatedParentProperty.Changed.Subscribe(e =>
            {
                var sender = e.Sender as TControl;

                if (sender != null)
                {
                    var logicalChild = logicalChildrenSelector(sender).FirstOrDefault() as IControl;
                    logicalChild?.SetValue(Control.TemplatedParentProperty, sender.TemplatedParent);
                }
            });

            TemplatedControl.TemplateProperty.Changed.Subscribe(e =>
            {
                var sender = e.Sender as TControl;

                if (sender != null)
                {
                    IDisposable subscription;

                    if (subscriptions.Value.TryGetValue(sender, out subscription))
                    {
                        subscription.Dispose();
                        subscriptions.Value.Remove(sender);
                    }
                }
            });
        }
Exemplo n.º 54
0
        private static bool ApplyBinding(object instance, PerspexProperty property, IBinding binding)
        {
            if (property != null)
            {
                ((IPerspexObject)instance).Bind(property, binding);
                return true;
            }

            return false;
        }
Exemplo n.º 55
0
 public XamlBinding GetBinding(PerspexObject po, PerspexProperty pp)
 {
     return this.bindings.First(xamlBinding => xamlBinding.Target == po && xamlBinding.TargetProperty == pp);
 }
Exemplo n.º 56
0
 public void ClearValue(PerspexProperty property)
 {
     throw new NotImplementedException();
 }
 public BindingTarget(PerspexObject @object, PerspexProperty property)
 {
     _obj = @object;
     _property = property;
 }
Exemplo n.º 58
0
 public object GetValue(PerspexProperty property)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 59
0
 public IObservable <T> GetObservable <T>(PerspexProperty <T> property)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 60
0
 /// <summary>
 /// Indicates that a property change should cause <see cref="InvalidateVisual"/> to be
 /// called.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <remarks>
 /// This method should be called in a control's static constructor for each property
 /// on the control which when changed should cause a redraw. This is similar to WPF's
 /// FrameworkPropertyMetadata.AffectsRender flag.
 /// </remarks>
 protected static void AffectsRender(PerspexProperty property)
 {
     property.Changed.Subscribe(AffectsRenderInvalidate);
 }