Esempio n. 1
0
        /// <summary>
        /// Retrieves the type of the dependency property with the specified name that
        /// matches the specified type filter.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="filter">The type filter for which to resolve a property type.</param>
        /// <param name="property">The property name for which to resolve a property type.</param>
        /// <returns>The type of the dependency property that was resolved.</returns>
        private static Type ResolvePropertyTypeFromFilter(UltravioletContext uv, IEnumerable <String> filter, ref String property)
        {
            var propertyName = property;

            var possiblePropertyMatches =
                from f in filter
                let elementType = ResolveKnownType(uv, f)
                                  let propertyID = DependencyProperty.FindByStylingName(propertyName, elementType)
                                                   let propertyType = (propertyID == null) ? null : propertyID.PropertyType
                                                                      where propertyType != null
                                                                      select new { PropertyID = propertyID, PropertyType = propertyType };

            var distinctNames = possiblePropertyMatches.Select(x => x.PropertyID.Name).Distinct();

            if (distinctNames.Count() > 1)
            {
                throw new InvalidOperationException(PresentationStrings.AmbiguousDependencyProperty.Format(property));
            }

            if (distinctNames.Any())
            {
                property = distinctNames.Single();
            }

            var distinctTypes = possiblePropertyMatches.Select(x => x.PropertyType).Distinct();

            if (distinctTypes.Count() > 1)
            {
                throw new InvalidOperationException(PresentationStrings.AmbiguousDependencyProperty.Format(property));
            }

            return(distinctTypes.FirstOrDefault());
        }
        /// <summary>
        /// Applies the current set of styles to the specified element.
        /// </summary>
        /// <param name="element">The element to which to apply the prioritizer's styles.</param>
        public void Apply(UIElement element)
        {
            foreach (var kvp in rules)
            {
                var style    = kvp.Value.Style;
                var selector = kvp.Value.Selector;
                var dprop    = DependencyProperty.FindByStylingName(element.Ultraviolet, element, style.Owner, style.Name);

                element.ApplyStyle(style, selector, kvp.Key.NavigationExpression, dprop);
            }

            foreach (var kvp in triggers)
            {
                if (kvp.Value.Trigger.Actions.Count == 0)
                {
                    continue;
                }

                var target = (DependencyObject)element;
                if (kvp.Key.NavigationExpression.HasValue)
                {
                    target = kvp.Key.NavigationExpression.Value.ApplyExpression(element.Ultraviolet, element);
                }

                if (target != null)
                {
                    kvp.Value.Trigger.AttachInternal(target, true);
                }
            }

            Reset();
        }
Esempio n. 3
0
        /// <inheritdoc/>
        protected override void Detach(DependencyObject dobj)
        {
            if (!IsAttachedTo(dobj))
            {
                return;
            }

            foreach (var condition in conditions)
            {
                var dprop = DependencyProperty.FindByStylingName(Ultraviolet, dobj, condition.PropertyName.Owner, condition.PropertyName.Name);
                if (dprop == null)
                {
                    throw new InvalidOperationException(PresentationStrings.EventOrPropertyDoesNotExist.Format(condition.PropertyName, dobj.GetType()));
                }

                DependencyProperty.UnregisterChangeNotification(dobj, dprop, this);
            }

            if (IsActivatedOn(dobj))
            {
                Deactivate(dobj);
            }

            base.Detach(dobj);
        }
        /// <summary>
        /// Evaluates whether the condition is true for the specified object.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="dobj">The object against which to evaluate the trigger condition.</param>
        /// <returns><see langword="true"/> if the condition is true for the specified object; otherwise, <see langword="false"/>.</returns>
        internal Boolean Evaluate(UltravioletContext uv, DependencyObject dobj)
        {
            Contract.Require(uv, nameof(uv));
            Contract.Require(dobj, nameof(dobj));

            var dprop = DependencyProperty.FindByStylingName(uv, dobj, propertyName.Owner, propertyName.Name);

            if (dprop == null)
            {
                return(false);
            }

            var refvalCacheType = (propertyValueCachhe == null) ? null : propertyValueCachhe.GetType();

            if (refvalCacheType == null || (refvalCacheType != dprop.PropertyType && refvalCacheType != dprop.UnderlyingType))
            {
                propertyValueCachhe = ObjectResolver.FromString(
                    propertyValue.Value, dprop.PropertyType, propertyValue.Culture);
            }

            var comparison = TriggerComparisonCache.Get(dprop.PropertyType, op);

            if (comparison == null)
            {
                throw new InvalidOperationException(PresentationStrings.InvalidTriggerComparison.Format(propertyName, op, dprop.PropertyType));
            }

            return(comparison(dobj, dprop, propertyValueCachhe));
        }
        /// <inheritdoc/>
        public override void Deactivate(UltravioletContext uv, DependencyObject dobj)
        {
            if (selector == null)
            {
                var dprop = DependencyProperty.FindByStylingName(uv, dobj, propertyName.Owner, propertyName.Name);
                if (dprop != null)
                {
                    dobj.ClearTriggeredValue(dprop, this);
                }
            }
            else
            {
                var element = dobj as UIElement;
                if (element != null && element.View != null)
                {
                    var rooted = selector.PartCount == 0 ? false :
                                 String.Equals(selector[0].PseudoClass, "trigger-root", StringComparison.InvariantCultureIgnoreCase);
                    var target = rooted ? dobj as UIElement : null;

                    element.View.Select(target, selector, this, (e, s) =>
                    {
                        var action = (SetTriggerAction)s;
                        var dprop  = DependencyProperty.FindByStylingName(e.Ultraviolet, e, action.propertyName.Owner, action.propertyName.Name);
                        if (dprop != null)
                        {
                            e.ClearTriggeredValue(dprop, action);
                        }
                    });
                }
            }
            base.Deactivate(uv, dobj);
        }
        /// <summary>
        /// Applies the navigation expression to the specified dependency object.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="source">The dependency object to which to apply the expression.</param>
        /// <returns>The dependency object that was navigated to, or <see langword="null"/> if no valid target was found.</returns>
        public DependencyObject ApplyExpression(UltravioletContext uv, DependencyObject source)
        {
            Contract.Require(uv, nameof(uv));
            Contract.Require(source, nameof(source));

            var dp = DependencyProperty.FindByStylingName(uv, source, propertyName.Owner, propertyName.Name);

            if (dp == null)
            {
                return(null);
            }

            var child = source.GetUntypedValue(dp) as DependencyObject;

            if (child != null)
            {
                var isIndexed   = propertyIndex.HasValue;
                var isList      = child is IList;
                var isIndexable = child is IIndexable;

                if (isIndexed)
                {
                    if (isIndexable)
                    {
                        var indexable = ((IIndexable)child);
                        var index     = propertyIndex.Value;
                        if (index < 0 || index >= indexable.Count)
                        {
                            return(null);
                        }

                        return(indexable[index] as DependencyObject);
                    }

                    if (isList)
                    {
                        var list  = ((IList)child);
                        var index = propertyIndex.Value;
                        if (index < 0 || index >= list.Count)
                        {
                            return(null);
                        }

                        return(list[index] as DependencyObject);
                    }

                    return(null);
                }

                return(child);
            }

            return(source);
        }