예제 #1
0
            public DependencyPropertyValue(DependencyObject owner, DependencyProperty property)
            {
                Contract.Require(owner, nameof(owner));
                Contract.Require(property, nameof(property));

                this.owner    = owner;
                this.property = property;
                this.comparer = BindingExpressions.GetComparisonFunction(typeof(T));
                this.metadata = property.GetMetadataForOwner(owner.GetType());
                this.flags    = DependencyPropertyValueFlags.None;

                if (typeof(T).IsClass)
                {
                    flags |= DependencyPropertyValueFlags.IsReferenceType;
                }
                if (typeof(T).IsValueType)
                {
                    flags |= DependencyPropertyValueFlags.IsValueType;
                }

                if (metadata.HasDefaultValue)
                {
                    this.defaultValue = (T)(metadata.DefaultValue ?? default(T));
                    if (IsCoerced)
                    {
                        this.coercedValue = metadata.CoerceValue(owner, this.defaultValue);
                    }
                }

                UpdateRequiresDigest(GetValue());
            }
        /// <summary>
        /// Initializes a new instance of the <see cref="DataBindingSetterBuilder"/> class.
        /// </summary>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source to which the value is being bound.</param>
        /// <param name="expression">The binding expression with which to bind the dependency property.</param>
        public DataBindingSetterBuilder(Type expressionType, Type dataSourceType, String expression)
            : base(dataSourceType)
        {
            this.boundType    = expressionType;
            this.delegateType = typeof(DataBindingSetter <>).MakeGenericType(expressionType);

            CreateReturnTarget();

            var path    = BindingExpressions.GetBindingMemberPathPart(expression);
            var current = AddDataSourceReference();
            var value   = AddValueParameter();

            if (current.Type.IsValueType)
            {
                return;
            }

            if (!AddValueAssignment(current, value, path))
            {
                return;
            }

            AddReturn();
            AddReturnLabel();

            var lambdaBody = Expression.Block(variables, expressions);
            var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

            lambdaExpression = lambda;
        }
예제 #3
0
        public DependencyBoundValueConverting(IDependencyPropertyValue value, Type expressionType, Type dataSourceType, String expression, Boolean coerceToString)
            : base(value, expressionType, dataSourceType, expression)
        {
            var expressionFormatString = BindingExpressions.GetBindingFormatStringPart(expression);

            SetFormatString(expressionFormatString);

            this.coerceToString       = coerceToString;
            this.cachedConvertedValue = GetFresh();
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataBindingSetterBuilder"/> class.
        /// </summary>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source to which the value is being bound.</param>
        /// <param name="expression">The binding expression with which to bind the dependency property.</param>
        public DataBindingSetterBuilder(Type expressionType, Type dataSourceType, String expression)
            : base(dataSourceType)
        {
            this.boundType    = expressionType;
            this.delegateType = typeof(DataBindingSetter <>).MakeGenericType(expressionType);

#if CODE_GEN_ENABLED
            CreateReturnTarget();

            var path    = BindingExpressions.GetBindingMemberPathPart(expression);
            var current = AddDataSourceReference();
            var value   = AddValueParameter();

            if (current.Type.IsValueType)
            {
                return;
            }

            if (!AddValueAssignment(current, value, path))
            {
                return;
            }

            AddReturn();
            AddReturnLabel();

            var lambdaBody = Expression.Block(variables, expressions);
            var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

            lambdaExpression = lambda;
#else
            var expParamDataSource = Expression.Parameter(typeof(Object), "dataSource");
            var expParamValue      = Expression.Parameter(boundType, "value");

            var implMethod = typeof(DataBindingSetterBuilder).GetMethod(nameof(ReflectionBasedImplementation),
                                                                        BindingFlags.NonPublic | BindingFlags.Static);

            var path     = BindingExpressions.GetBindingMemberPathPart(expression);
            var property = dataSourceType.GetProperty(path);

            if (!property.CanWrite)
            {
                return;
            }

            var expImplMethodCall = Expression.Call(implMethod,
                                                    Expression.Constant(property),
                                                    Expression.Convert(expParamDataSource, typeof(Object)),
                                                    Expression.Convert(expParamValue, typeof(Object)));

            lambdaExpression = Expression.Lambda(delegateType, expImplMethodCall, expParamDataSource, expParamValue);
#endif
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DataBindingGetterBuilder"/> class.
        /// </summary>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source to which the expression is being bound.</param>
        /// <param name="expression">The binding expression with which to bind the dependency property.</param>
        public DataBindingGetterBuilder(Type expressionType, Type dataSourceType, String expression)
            : base(dataSourceType)
        {
            this.delegateType = typeof(DataBindingGetter <>).MakeGenericType(expressionType);

#if CODE_GEN_ENABLED
            CreateReturnTarget(expressionType);

            var path    = BindingExpressions.GetBindingMemberPathPart(expression);
            var current = AddDataSourceReference();

            current = AddSafeReference(expression, current, path);

            var result = Expression.Convert(current, expressionType);

            AddReturn(result);
            AddReturnLabel();

            var lambdaBody = Expression.Block(variables, expressions);
            var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

            lambdaExpression = lambda;
#else
            var expParamDataSource = Expression.Parameter(typeof(Object), "dataSource");

            var implMethod = typeof(DataBindingGetterBuilder).GetMethod(nameof(ReflectionBasedImplementation),
                                                                        BindingFlags.NonPublic | BindingFlags.Static);

            var path     = BindingExpressions.GetBindingMemberPathPart(expression);
            var property = dataSourceType.GetProperty(path);

            if (!property.CanRead)
            {
                return;
            }

            var expImplMethodCall = Expression.Call(implMethod,
                                                    Expression.Constant(property),
                                                    Expression.Convert(expParamDataSource, typeof(Object)));

            lambdaExpression = Expression.Lambda(delegateType,
                                                 Expression.Convert(
                                                     Expression.Convert(expImplMethodCall, property.PropertyType),
                                                     expressionType), expParamDataSource);
#endif
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DependencyBoundValue{TDependency}"/> class.
        /// </summary>
        /// <param name="value">The dependency property value which created this object.</param>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source.</param>
        /// <param name="expression">The binding expression.</param>
        public DependencyBoundValue(IDependencyPropertyValue value, Type expressionType, Type dataSourceType, String expression)
        {
            this.dependencyValue = value;
            this.getter          = (DataBindingGetter <T>)BindingExpressions.CreateBindingGetter(expressionType, dataSourceType, expression);
            this.setter          = (DataBindingSetter <T>)BindingExpressions.CreateBindingSetter(expressionType, dataSourceType, expression);
            this.comparer        = BindingExpressions.GetComparisonFunction(expressionType);
            this.cachedValue     = GetUnderlyingValue();
            this.dpropReference  = BindingExpressions.GetSimpleDependencyProperty(dataSourceType, expression);

            if (dpropReference != null)
            {
                var dataSource = value.Owner.DependencyDataSource;
                if (dataSource != null)
                {
                    HookDependencyProperty(dataSource);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BoundEventBuilder"/> type.
        /// </summary>
        /// <param name="dataSource">The data source to which the event is being bound.</param>
        /// <param name="dataSourceType">The type of the data source to which the expression is being bound.</param>
        /// <param name="delegateType">The type of delegate that will be created to bind to the event.</param>
        /// <param name="expression">The binding expression that represents the method to bind to the event.</param>
        public BoundEventBuilder(Object dataSource, Type dataSourceType, Type delegateType, String expression)
            : base(dataSourceType)
        {
            CreateParameters(delegateType);
            CreateReturnTarget();

            var path    = BindingExpressions.GetBindingMemberPathPart(expression, false);
            var current = AddDataSourceReference(expression, dataSource, dataSourceType);

            current = AddMethodInvocation(expression, current, path);

            AddReturn();
            AddReturnLabel();

            var lambdaBody = Expression.Block(variables, expressions);
            var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

            lambdaExpression = lambda;
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataBindingGetterBuilder"/> class.
        /// </summary>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source to which the expression is being bound.</param>
        /// <param name="expression">The binding expression with which to bind the dependency property.</param>
        public DataBindingGetterBuilder(Type expressionType, Type dataSourceType, String expression)
            : base(dataSourceType)
        {
            this.delegateType = typeof(DataBindingGetter <>).MakeGenericType(expressionType);

            CreateReturnTarget(expressionType);

            var path    = BindingExpressions.GetBindingMemberPathPart(expression);
            var current = AddDataSourceReference();

            current = AddSafeReference(expression, current, path);

            var result = Expression.Convert(current, expressionType);

            AddReturn(result);
            AddReturnLabel();

            var lambdaBody = Expression.Block(variables, expressions);
            var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

            lambdaExpression = lambda;
        }
예제 #9
0
            /// <summary>
            /// Creates the dependency property's cached bound value object.
            /// </summary>
            /// <param name="dataSourceType">The type of the data source to which the dependency property is bound.</param>
            /// <param name="expression">The dependency property's binding expression.</param>
            private void CreateCachedBoundValue(Type dataSourceType, String expression)
            {
                var expressionType = BindingExpressions.GetExpressionType(dataSourceType, expression);

                if (expressionType != null && TypesRequireSpecialConversion(expressionType, typeof(T)))
                {
                    var coerce    = typeof(T) == typeof(Object) && metadata.CoerceObjectToString;
                    var valueType = typeof(DependencyBoundValueConverting <,>).MakeGenericType(typeof(T), expressionType);
                    var valueCtor = default(Delegate);

                    lock (cachedBoundValueCtors)
                        cachedBoundValueCtors.TryGetValue(valueType, out valueCtor);

                    if (valueCtor == null)
                    {
                        valueCtor = CreateDependencyPropertyBoundValueConvertingCtor(valueType);
                    }

                    var valueInstance = ((DependencyBoundValueConvertingCtor <T>)valueCtor)(this, expressionType, dataSourceType, expression, coerce);
                    cachedBoundValue = valueInstance;
                }
                else
                {
                    var valueType = typeof(DependencyBoundValueNonConverting <>).MakeGenericType(typeof(T));
                    var valueCtor = default(Delegate);

                    lock (cachedBoundValueCtors)
                        cachedBoundValueCtors.TryGetValue(valueType, out valueCtor);

                    if (valueCtor == null)
                    {
                        valueCtor = CreateDependencyPropertyBoundValueNonConvertingCtor(valueType);
                    }

                    var valueInstance = ((DependencyBoundValueNonConvertingCtor <T>)valueCtor)(this, typeof(T), dataSourceType, expression);
                    cachedBoundValue = valueInstance;
                }
            }
예제 #10
0
        /// <summary>
        /// Determines whether the specified target is a dependency property, routed event, or standard property/event.
        /// </summary>
        private static UvmlMutatorTarget GetMutatorTarget(UltravioletContext uv,
                                                          String name, String value, Type type, out Object target, out Type targetType)
        {
            var upf = uv.GetUI().GetPresentationFoundation();

            // If this is an attached property/event, find the owner type.
            var depname = new DependencyName(name);

            if (depname.IsAttached)
            {
                var attachedOwnerType = default(Type);
                if (!upf.GetKnownType(depname.Owner, out attachedOwnerType))
                {
                    throw new UvmlException(PresentationStrings.UnrecognizedType.Format(depname.Owner));
                }

                type = attachedOwnerType;
            }

            // Is it a dependency property?
            var dprop = DependencyProperty.FindByName(depname.Name, type);

            if (dprop != null)
            {
                target = dprop;
                if (value != null && BindingExpressions.IsBindingExpression(value))
                {
                    targetType = typeof(String);
                    return(UvmlMutatorTarget.DependencyPropertyBinding);
                }
                targetType = dprop.PropertyType;
                return(UvmlMutatorTarget.DependencyProperty);
            }

            // Is it a routed event?
            var revt = EventManager.FindByName(depname.Name, type);

            if (revt != null)
            {
                target     = revt;
                targetType = typeof(String);
                return(UvmlMutatorTarget.RoutedEvent);
            }

            // Is it a standard property?
            var clrprop = type.GetProperty(depname.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (clrprop != null)
            {
                target     = clrprop;
                targetType = clrprop.PropertyType;
                return(UvmlMutatorTarget.StandardProperty);
            }

            // Is it a standard event?
            var clrevt = type.GetEvent(depname.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (clrevt != null)
            {
                target     = clrevt;
                targetType = typeof(String);
                return(UvmlMutatorTarget.StandardEvent);
            }

            throw new UvmlException(PresentationStrings.EventOrPropertyDoesNotExist.Format(depname.Name, type.Name));
        }