/// <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(); }
/// <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); }