protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            ILogical c = (ILogical)control;
            List <IObservable <bool> > descendantMatches = new List <IObservable <bool> >();

            while (c != null)
            {
                c = c.LogicalParent;

                if (c is IStyleable)
                {
                    var match = _parent.Match((IStyleable)c, subscribe);

                    if (match.Result == SelectorMatchResult.Sometimes)
                    {
                        descendantMatches.Add(match.Activator);
                    }
                    else if (match.IsMatch)
                    {
                        return(SelectorMatch.AlwaysThisInstance);
                    }
                }
            }

            if (descendantMatches.Count > 0)
            {
                return(new SelectorMatch(StyleActivator.Or(descendantMatches)));
            }
            else
            {
                return(SelectorMatch.NeverThisInstance);
            }
        }
        /// <summary>
        /// Tries to match the selector with a control.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="subscribe">
        /// Whether the match should subscribe to changes in order to track the match over time,
        /// or simply return an immediate result.
        /// </param>
        /// <returns>A <see cref="SelectorMatch"/>.</returns>
        public SelectorMatch Match(IStyleable control, bool subscribe = true)
        {
            List <IObservable <bool> > inputs = new List <IObservable <bool> >();
            Selector selector = this;

            while (selector != null)
            {
                if (selector.InTemplate && control.TemplatedParent == null)
                {
                    return(SelectorMatch.False);
                }

                var match = selector.Evaluate(control, subscribe);

                if (match.ImmediateResult == false)
                {
                    return(match);
                }
                else if (match.ObservableResult != null)
                {
                    inputs.Add(match.ObservableResult);
                }

                selector = selector.MovePrevious();
            }

            if (inputs.Count > 0)
            {
                return(new SelectorMatch(StyleActivator.And(inputs)));
            }
            else
            {
                return(SelectorMatch.True);
            }
        }
예제 #3
0
        /// <summary>
        /// Tries to match the selector with a control.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="subscribe">
        /// Whether the match should subscribe to changes in order to track the match over time,
        /// or simply return an immediate result.
        /// </param>
        /// <returns>A <see cref="SelectorMatch"/>.</returns>
        public SelectorMatch Match(IStyleable control, bool subscribe = true)
        {
            ValueSingleOrList <IObservable <bool> > inputs = default;

            var selector       = this;
            var alwaysThisType = true;
            var hitCombinator  = false;

            while (selector != null)
            {
                hitCombinator |= selector.IsCombinator;

                var match = selector.Evaluate(control, subscribe);

                if (!match.IsMatch)
                {
                    return(hitCombinator ? SelectorMatch.NeverThisInstance : match);
                }
                else if (selector.InTemplate && control.TemplatedParent == null)
                {
                    return(SelectorMatch.NeverThisInstance);
                }
                else if (match.Result == SelectorMatchResult.AlwaysThisInstance)
                {
                    alwaysThisType = false;
                }
                else if (match.Result == SelectorMatchResult.Sometimes)
                {
                    Debug.Assert(match.Activator != null);

                    inputs.Add(match.Activator);
                }

                selector = selector.MovePrevious();
            }

            if (inputs.HasList)
            {
                return(new SelectorMatch(StyleActivator.And(inputs.List)));
            }
            else if (inputs.IsSingle)
            {
                return(new SelectorMatch(inputs.Single));
            }
            else
            {
                return(alwaysThisType && !hitCombinator ?
                       SelectorMatch.AlwaysThisType :
                       SelectorMatch.AlwaysThisInstance);
            }
        }
예제 #4
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            var activators        = new List <IObservable <bool> >();
            var neverThisInstance = false;

            foreach (var selector in _selectors)
            {
                var match = selector.Match(control, subscribe);

                switch (match.Result)
                {
                case SelectorMatchResult.AlwaysThisType:
                case SelectorMatchResult.AlwaysThisInstance:
                    return(match);

                case SelectorMatchResult.NeverThisInstance:
                    neverThisInstance = true;
                    break;

                case SelectorMatchResult.Sometimes:
                    activators.Add(match.Activator);
                    break;
                }
            }

            if (activators.Count > 1)
            {
                return(new SelectorMatch(StyleActivator.Or(activators)));
            }
            else if (activators.Count == 1)
            {
                return(new SelectorMatch(activators[0]));
            }
            else if (neverThisInstance)
            {
                return(SelectorMatch.NeverThisInstance);
            }
            else
            {
                return(SelectorMatch.NeverThisType);
            }
        }
예제 #5
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            ILogical c = (ILogical)control;
            List <IObservable <bool> > descendantMatches = new List <IObservable <bool> >();

            while (c != null)
            {
                c = c.LogicalParent;

                if (c is IStyleable)
                {
                    var match = _parent.Match((IStyleable)c, subscribe);

                    if (match.ImmediateResult != null)
                    {
                        if (match.ImmediateResult == true)
                        {
                            return(SelectorMatch.True);
                        }
                    }
                    else
                    {
                        descendantMatches.Add(match.ObservableResult);
                    }
                }
            }

            if (descendantMatches.Count > 0)
            {
                return(new SelectorMatch(StyleActivator.Or(descendantMatches)));
            }
            else
            {
                return(SelectorMatch.False);
            }
        }