Exemple #1
0
        /// <summary>
        /// Remove a binding between a property of this class and a property of a
        /// target class.
        /// </summary>
        /// <param name="source">Source property.</param>
        /// <param name="target">Target <see cref="pObject"/> which have the target property.</param>
        /// <param name="destinationProperty">Target property.</param>
        public void Unbind(string source, pObject target, string destinationProperty)
        {
            try
            {
                var binding = propagationVectors[source].FindIndex(x =>
                {
                    x.Instance.TryGetTarget(out pObject t);
                    return(t == target && x.Property.Name == destinationProperty);
                });

                if (binding < 0)
                {
                    throw new InvalidOperationException("Invalid binding.");
                }

                // Check if the remote part is not disposed.
                if (propagationVectors[source][binding].Instance.TryGetTarget(out pObject obj) && obj != null)
                {
                    var remote = target.propagationVectors[destinationProperty].FindIndex(x =>
                    {
                        x.Instance.TryGetTarget(out pObject t);
                        return(t == this && x.Property.Name == source);
                    });

                    if (remote >= 0)
                    {
                        target.propagationVectors[destinationProperty].RemoveAt(remote);
                    }

                    if (target.propagationVectors[destinationProperty].Count == 0)
                    {
                        target.propagationVectors.Remove(destinationProperty);
                    }
                }

                propagationVectors[source].RemoveAt(binding);

                if (propagationVectors[source].Count == 0)
                {
                    propagationVectors.Remove(source);
                }
            }
            catch (KeyNotFoundException)
            {
                throw new InvalidOperationException("Property does not exist.");
            }
        }
Exemple #2
0
        /// <summary>
        /// Set a binding between a property of this class and a property of a
        /// target class.
        /// </summary>
        /// <param name="source">Source property.</param>
        /// <param name="target">Target <see cref="pObject"/> which have the target property.</param>
        /// <param name="destinationProperty">Target property to bind.</param>
        /// <param name="direction">Binding direction.</param>
        /// <param name="adapterToDestination">Function that convert the value to the destination variable type.</param>
        /// <param name="adapterToSource">Function that convert the value to the source variable type.</param>
        public void Bind(string source, pObject target, string destinationProperty, BindingMode direction, Func <object, object> adapterToDestination, Func <object, object> adapterToSource)
        {
            var sourceType      = GetType();
            var sourceProperty  = sourceType.GetProperty(source);
            var destinationType = GetType();
            var destProperty    = sourceType.GetProperty(destinationProperty);

            Bindable sourceAttribute = null;
            Bindable destAttribute   = null;

            if (source == destinationProperty && target == this)
            {
                throw new Exception("Cannot bind a property to itself.");
            }

            if (sourceProperty.PropertyType != destProperty.PropertyType)
            {
                switch (direction)
                {
                case BindingMode.TwoWay:
                    if (adapterToDestination == null || adapterToSource == null)
                    {
                        throw new InvalidOperationException("Binding between two different types without adapter.");
                    }
                    break;

                case BindingMode.ReadOnly:
                    if (adapterToDestination == null)
                    {
                        throw new InvalidOperationException("Binding between two different types without adapter.");
                    }
                    break;

                case BindingMode.WriteOnly:
                    if (adapterToSource == null)
                    {
                        throw new InvalidOperationException("Binding between two different types without adapter.");
                    }
                    break;

                default:
                    throw new InvalidOperationException("Binding mode not supported.");
                }
            }

            try
            {
                sourceAttribute = sourceProperty.GetCustomAttribute(typeof(Bindable)) as Bindable;
                destAttribute   = destProperty.GetCustomAttribute(typeof(Bindable)) as Bindable;
            }
            catch (NullReferenceException)
            {
                throw new InvalidOperationException("One of this properties has no bindable attribute");
            }

            if (sourceAttribute == null || destAttribute == null)
            {
                throw new InvalidOperationException("One of this properties has no bindable attribute");
            }

            switch (direction)
            {
            case BindingMode.TwoWay:
                if (sourceAttribute.Direction != BindingMode.TwoWay ||
                    destAttribute.Direction != BindingMode.TwoWay)
                {
                    throw new InvalidOperationException("TwoWay binding is not allowed for this binding.");
                }
                break;

            case BindingMode.ReadOnly:
                if ((sourceAttribute.Direction != BindingMode.WriteOnly && sourceAttribute.Direction != BindingMode.TwoWay) ||
                    (destAttribute.Direction != BindingMode.TwoWay && destAttribute.Direction != BindingMode.ReadOnly))
                {
                    throw new InvalidOperationException("ReadOnly binding is not allowed for this binding.");
                }
                break;

            case BindingMode.WriteOnly:
                if ((sourceAttribute.Direction != BindingMode.ReadOnly && sourceAttribute.Direction != BindingMode.TwoWay) ||
                    (destAttribute.Direction != BindingMode.TwoWay && destAttribute.Direction != BindingMode.WriteOnly))
                {
                    throw new InvalidOperationException("WriteOnly binding is not allowed for this binding.");
                }
                break;

            default:
                throw new InvalidOperationException("Binding mode not supported.");
            }

            var sourceBindingInformations = new BindingInformations
            {
                Instance  = new WeakReference <pObject>(target),
                Property  = target.GetType().GetProperty(destinationProperty),
                Direction = direction,
                Adapter   = adapterToDestination
            };

            BindingMode invertedDirection = BindingMode.TwoWay;

            switch (direction)
            {
            case BindingMode.ReadOnly: invertedDirection = BindingMode.WriteOnly; break;

            case BindingMode.WriteOnly: invertedDirection = BindingMode.ReadOnly; break;

            case BindingMode.TwoWay: invertedDirection = BindingMode.TwoWay; break;

            default:
                throw new InvalidOperationException("Binding mode not supported.");
            }

            var destBindingInformations = new BindingInformations
            {
                Instance  = new WeakReference <pObject>(this),
                Property  = GetType().GetProperty(source),
                Direction = invertedDirection,
                Adapter   = adapterToSource
            };

            SetPropagationVector(source, sourceBindingInformations);
            target.SetPropagationVector(destinationProperty, destBindingInformations);

            checkBindings(this, new System.ComponentModel.PropertyChangedEventArgs(source));
            target.checkBindings(this, new System.ComponentModel.PropertyChangedEventArgs(destinationProperty));
        }
Exemple #3
0
 /// <summary>
 /// Set a binding between a property of this class and a property of a
 /// target class.
 /// </summary>
 /// <param name="source">Source property.</param>
 /// <param name="target">Target <see cref="pObject"/> which have the target property.</param>
 /// <param name="destinationProperty">Target property to bind.</param>
 /// <param name="adapterToDestination">Function that convert the value to the destination variable type.</param>
 /// <param name="adapterToSource">Function that convert the value to the source variable type.</param>
 public void Bind(string source, pObject target, string destinationProperty, Func <object, object> adapterToDestination, Func <object, object> adapterToSource)
 {
     Bind(source, target, destinationProperty, BindingMode.TwoWay, adapterToDestination, adapterToSource);
 }
Exemple #4
0
 /// <summary>
 /// Set a binding between a property of this class and a property of a
 /// target class.
 /// </summary>
 /// <param name="source">Source property.</param>
 /// <param name="target">Target <see cref="pObject"/> which have the target property.</param>
 /// <param name="destinationProperty">Target property to bind.</param>
 /// <param name="direction">Binding direction.</param>
 public void Bind(string source, pObject target, string destinationProperty, BindingMode direction)
 {
     Bind(source, target, destinationProperty, direction, null, null);
 }
Exemple #5
0
 /// <summary>
 /// Set a binding between a property of this class and a property of a
 /// target class.
 /// </summary>
 /// <param name="source">Source property.</param>
 /// <param name="target">Target <see cref="pObject"/> which have the target property.</param>
 /// <param name="destinationProperty">Target property to bind.</param>
 public void Bind(string source, pObject target, string destinationProperty)
 {
     Bind(source, target, destinationProperty, BindingMode.TwoWay, null, null);
 }