예제 #1
0
        /// <summary>
        /// Binds a <see cref="AvaloniaProperty"/> to an observable.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="source">The observable.</param>
        /// <param name="priority">The priority of the binding.</param>
        /// <returns>
        /// A disposable which can be used to terminate the binding.
        /// </returns>
        public IDisposable Bind(
            AvaloniaProperty property,
            IObservable <object> source,
            BindingPriority priority = BindingPriority.LocalValue)
        {
            Contract.Requires <ArgumentNullException>(property != null);
            Contract.Requires <ArgumentNullException>(source != null);

            VerifyAccess();

            var description = GetDescription(source);

            if (property.IsDirect)
            {
                if (property.IsReadOnly)
                {
                    throw new ArgumentException($"The property {property.Name} is readonly.");
                }

                Logger.Verbose(
                    LogArea.Property,
                    this,
                    "Bound {Property} to {Binding} with priority LocalValue",
                    property,
                    description);

                if (_directBindings == null)
                {
                    _directBindings = new List <DirectBindingSubscription>();
                }

                return(new DirectBindingSubscription(this, property, source));
            }
            else
            {
                Logger.Verbose(
                    LogArea.Property,
                    this,
                    "Bound {Property} to {Binding} with priority {Priority}",
                    property,
                    description,
                    priority);

                if (_values == null)
                {
                    _values = new ValueStore(this);
                }

                return(_values.AddBinding(property, source, priority));
            }
        }
예제 #2
0
        /// <summary>
        /// Sets the value of a styled property.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="value">The value.</param>
        /// <param name="priority">The priority of the value.</param>
        private void SetStyledValue(AvaloniaProperty property, object value, BindingPriority priority)
        {
            var notification = value as BindingNotification;

            // We currently accept BindingNotifications for non-direct properties but we just
            // strip them to their underlying value.
            if (notification != null)
            {
                if (!notification.HasValue)
                {
                    return;
                }
                else
                {
                    value = notification.Value;
                }
            }

            var originalValue = value;

            if (!TypeUtilities.TryConvertImplicit(property.PropertyType, value, out value))
            {
                throw new ArgumentException(string.Format(
                                                "Invalid value for Property '{0}': '{1}' ({2})",
                                                property.Name,
                                                originalValue,
                                                originalValue?.GetType().FullName ?? "(null)"));
            }

            if (_values == null)
            {
                _values = new ValueStore(this);
            }

            LogPropertySet(property, value, priority);
            _values.AddValue(property, value, (int)priority);
        }