Пример #1
0
        /// <summary>
        /// Attaches the style to a control if the style's selector matches.
        /// </summary>
        /// <param name="control">The control to attach to.</param>
        /// <param name="container">
        /// The control that contains this style. May be null.
        /// </param>
        public void Attach(IStyleable control, IStyleHost container)
        {
            if (Selector != null)
            {
                var match = Selector.Match(control);

                if (match.ImmediateResult != false)
                {
                    var subs = GetSubscriptions(control);

                    foreach (var setter in Setters)
                    {
                        var sub = setter.Apply(this, control, match.ObservableResult);
                        subs.Add(sub);
                    }
                }
            }
            else if (control == container)
            {
                var subs = GetSubscriptions(control);

                foreach (var setter in Setters)
                {
                    var sub = setter.Apply(this, control, null);
                    subs.Add(sub);
                }
            }
        }
Пример #2
0
 /// <inheritdoc/>
 public void Attach(IStyleable control, IStyleHost container)
 {
     if (Source != null)
     {
         Loaded.Attach(control, container);
     }
 }
Пример #3
0
        /// <summary>
        /// Attaches the style to a control if the style's selector matches.
        /// </summary>
        /// <param name="control">The control to attach to.</param>
        /// <param name="container">
        /// The control that contains this style. May be null.
        /// </param>
        public void Attach(IStyleable control, IStyleHost container)
        {
            if (Selector != null)
            {
                var description = "Style " + Selector.ToString();
                var match = Selector.Match(control);

                if (match.ImmediateResult != false)
                {
                    var activator = (match.ObservableResult ?? True)
                        .TakeUntil(control.StyleDetach);

                    foreach (var setter in Setters)
                    {
                        setter.Apply(this, control, activator);
                    }
                }
            }
            else if (control == container)
            {
                foreach (var setter in Setters)
                {
                    setter.Apply(this, control, null);
                }
            }
        }
Пример #4
0
        public SelectorMatch Match(IStyleable control)
        {
            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);

                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(new StyleActivator(inputs));
            }
            else
            {
                return SelectorMatch.True;
            }
        }
Пример #5
0
        /// <inheritdoc/>
        public bool Attach(IStyleable control, IStyleHost container)
        {
            if (Source != null)
            {
                return(Loaded.Attach(control, container));
            }

            return(false);
        }
Пример #6
0
        public void ApplyStyles(IStyleable target)
        {
            target = target ?? throw new ArgumentNullException(nameof(target));

            if (target is IStyleHost styleHost)
            {
                ApplyStyles(target, styleHost);
            }
        }
Пример #7
0
        public void ApplyStyles(IStyleable control)
        {
            var styleHost = control as IStyleHost;

            if (styleHost != null)
            {
                ApplyStyles(control, styleHost);
            }
        }
 public PropertySetterLazyInstance(
     IStyleable target,
     DirectPropertyBase <T> property,
     Func <T> valueFactory)
 {
     _target         = target;
     _directProperty = property;
     _valueFactory   = valueFactory;
 }
 public PropertySetterInstance(
     IStyleable target,
     DirectPropertyBase <T> property,
     T value)
 {
     _target         = target;
     _directProperty = property;
     _value          = value;
 }
 public PropertyEqualsActivator(
     IStyleable control,
     AvaloniaProperty property,
     object?value)
 {
     _control  = control ?? throw new ArgumentNullException(nameof(control));
     _property = property ?? throw new ArgumentNullException(nameof(property));
     _value    = value;
 }
        protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe)
        {
            if (parent is Style s && s.Selector is Selector selector)
            {
                return(selector.Match(control, (parent as Style)?.Parent, subscribe));
            }

            throw new InvalidOperationException(
                      "Nesting selector was specified but cannot determine parent selector.");
        }
Пример #12
0
 public PropertySetterBindingInstance(
     IStyleable target,
     DirectPropertyBase <T> property,
     IBinding binding)
 {
     _target         = target;
     _directProperty = property;
     _binding        = binding.Initiate(_target, property);
     _inner          = new Inner(this);
 }
Пример #13
0
 private static SelectorMatch MatchPropertyEquals(IStyleable x, PerspexProperty property, object value)
 {
     if (!PerspexPropertyRegistry.Instance.IsRegistered(x, property))
     {
         return(SelectorMatch.False);
     }
     else
     {
         return(new SelectorMatch(x.GetObservable(property).Select(v => Equals(v, value))));
     }
 }
        protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe)
        {
            var templatedParent = control.TemplatedParent as IStyleable;

            if (templatedParent == null)
            {
                return(SelectorMatch.NeverThisInstance);
            }

            return(_parent.Match(templatedParent, parent, subscribe));
        }
Пример #15
0
 /// <inheritdoc/>
 protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
 {
     if (subscribe)
     {
         return(new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v ?? string.Empty, _value))));
     }
     else
     {
         return(new SelectorMatch((control.GetValue(_property) ?? string.Empty).Equals(_value)));
     }
 }
Пример #16
0
        /// <summary>
        /// Called when a control's <see cref="IStyleable.StyleDetach"/> is signalled to remove
        /// all applied styles.
        /// </summary>
        /// <param name="control">The control.</param>
        private static void ControlDetach(IStyleable control)
        {
            var subscriptions = _applied[control];

            foreach (var subscription in subscriptions)
            {
                subscription.Dispose();
            }

            _applied.Remove(control);
        }
Пример #17
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            IStyleable templatedParent = control.TemplatedParent as IStyleable;

            if (templatedParent == null)
            {
                throw new InvalidOperationException(
                          "Cannot call Template selector on control with null TemplatedParent.");
            }

            return(_parent.Match(templatedParent, subscribe) ?? SelectorMatch.True);
        }
 protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
 {
     if (subscribe)
     {
         return(new SelectorMatch(new PropertyEqualsActivator(control, _property, _value)));
     }
     else
     {
         var result = (control.GetValue(_property) ?? string.Empty).Equals(_value);
         return(result ? SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance);
     }
 }
Пример #19
0
        private static SelectorMatch MatchTemplate(IStyleable control, Selector previous)
        {
            IStyleable templatedParent = control.TemplatedParent as IStyleable;

            if (templatedParent == null)
            {
                throw new InvalidOperationException(
                          "Cannot call Template selector on control with null TemplatedParent.");
            }

            return(previous.Match(templatedParent));
        }
Пример #20
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            IStyleable templatedParent = control.TemplatedParent as IStyleable;

            if (templatedParent == null)
            {
                throw new InvalidOperationException(
                    "Cannot call Template selector on control with null TemplatedParent.");
            }

            return _parent.Match(templatedParent, subscribe) ?? SelectorMatch.True;
        }
Пример #21
0
        static Thickness Merge(IStyleable control, AvaloniaProperty <Thickness> property, Thickness newValue)
        {
            var oldValue = control.GetValue <Thickness>(property);

            return(new Thickness
                   (
                       left:   double.IsNaN(newValue.Left)   ? oldValue.Left   : newValue.Left,
                       top:    double.IsNaN(newValue.Top)    ? oldValue.Top    : newValue.Top,
                       right:  double.IsNaN(newValue.Right)  ? oldValue.Right  : newValue.Right,
                       bottom: double.IsNaN(newValue.Bottom) ? oldValue.Bottom : newValue.Bottom
                   ));
        }
Пример #22
0
 /// <summary>
 /// Applies the setter to the control.
 /// </summary>
 /// <param name="style">The style that is being applied.</param>
 /// <param name="control">The control.</param>
 /// <param name="activator">An optional activator.</param>
 public void Apply(IStyle style, IStyleable control, IObservable <bool> activator)
 {
     if (activator == null)
     {
         control.SetValue(Property, Value, BindingPriority.Style);
     }
     else
     {
         var binding = new StyleBinding(activator, Value, style.ToString());
         control.Bind(Property, binding, BindingPriority.StyleTrigger);
     }
 }
Пример #23
0
 /// <summary>
 /// Applies the setter to the control.
 /// </summary>
 /// <param name="style">The style that is being applied.</param>
 /// <param name="control">The control.</param>
 /// <param name="activator">An optional activator.</param>
 public void Apply(IStyle style, IStyleable control, IObservable<bool> activator)
 {
     if (activator == null)
     {
         control.Bind(Property, Source, BindingPriority.Style);
     }
     else
     {
         var binding = new StyleBinding(activator, Source, style.ToString());
         control.Bind(Property, binding, BindingPriority.StyleTrigger);
     }
 }
Пример #24
0
        private static SelectorMatch MatchClass(IStyleable control, string name)
        {
            var observable = Observable.FromEventPattern <
                NotifyCollectionChangedEventHandler,
                NotifyCollectionChangedEventArgs>(
                x => control.Classes.CollectionChanged += x,
                x => control.Classes.CollectionChanged -= x)
                             .Select(_ => Unit.Default)
                             .StartWith(Unit.Default)
                             .Select(_ => control.Classes.Contains(name));

            return(new SelectorMatch(observable));
        }
Пример #25
0
        /// <inheritdoc/>
        public void Attach(IStyleable control, IStyleHost container)
        {
            if (Source != null)
            {
                if (Loaded == null)
                {
                    var loader = new PerspexXamlLoader();
                    Loaded = (IStyle)loader.Load(Source);
                }

                Loaded.Attach(control, container);
            }
        }
Пример #26
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            var controlParent = ((ILogical)control).LogicalParent;

            if (controlParent != null)
            {
                return _parent.Match((IStyleable)controlParent, subscribe);
            }
            else
            {
                return SelectorMatch.False;
            }
        }
 protected override SelectorMatch Evaluate(IStyleable control, IStyle?parent, bool subscribe)
 {
     if (subscribe)
     {
         return(new SelectorMatch(new PropertyEqualsActivator(control, _property, _value)));
     }
     else
     {
         return(Compare(_property.PropertyType, control.GetValue(_property), _value)
             ? SelectorMatch.AlwaysThisInstance
             : SelectorMatch.NeverThisInstance);
     }
 }
Пример #28
0
        /// <inheritdoc/>
        public void Attach(IStyleable control, IStyleHost container)
        {
            if (Source != null)
            {
                if (Loaded == null)
                {
                    var loader = new PerspexXamlLoader();
                    Loaded = (IStyle)loader.Load(Source);
                }

                Loaded.Attach(control, container);
            }
        }
Пример #29
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            var controlParent = ((ILogical)control).LogicalParent;

            if (controlParent != null)
            {
                return(_parent.Match((IStyleable)controlParent, subscribe));
            }
            else
            {
                return(SelectorMatch.False);
            }
        }
Пример #30
0
        private static SelectorMatch MatchChild(IStyleable control, Selector previous)
        {
            var parent = ((ILogical)control).LogicalParent;

            if (parent != null)
            {
                return(previous.Match((IStyleable)parent));
            }
            else
            {
                return(SelectorMatch.False);
            }
        }
Пример #31
0
        private static List <IDisposable> GetSubscriptions(IStyleable control)
        {
            List <IDisposable> subscriptions;

            if (!_applied.TryGetValue(control, out subscriptions))
            {
                subscriptions = new List <IDisposable>(2);
                subscriptions.Add(control.StyleDetach.Subscribe(ControlDetach));
                _applied.Add(control, subscriptions);
            }

            return(subscriptions);
        }
Пример #32
0
        /// <summary>
        /// Attaches the style to a control if the style's selector matches.
        /// </summary>
        /// <param name="control">The control to attach to.</param>
        public void Attach(IStyleable control)
        {
            var description = "Style " + Selector.ToString();
            var match = Selector.Match(control);

            if (match.ImmediateResult != false)
            {
                foreach (var setter in Setters)
                {
                    setter.Apply(this, control, match.ObservableResult);
                }
            }
        }
Пример #33
0
        /// <summary>
        /// Attaches the style to a control if the style's selector matches.
        /// </summary>
        /// <param name="control">The control to attach to.</param>
        public void Attach(IStyleable control)
        {
            var description = "Style " + Selector.ToString();
            var match       = Selector.Match(control);

            if (match.ImmediateResult != false)
            {
                foreach (var setter in Setters)
                {
                    setter.Apply(this, control, match.ObservableResult);
                }
            }
        }
Пример #34
0
        /// <inheritdoc/>
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            if (TargetType != null)
            {
                var controlType = control.StyleKey ?? control.GetType();

                if (IsConcreteType)
                {
                    if (controlType != TargetType)
                    {
                        return(SelectorMatch.False);
                    }
                }
                else
                {
                    if (!TargetType.GetTypeInfo().IsAssignableFrom(controlType.GetTypeInfo()))
                    {
                        return(SelectorMatch.False);
                    }
                }
            }

            if (Name != null && control.Name != Name)
            {
                return(SelectorMatch.False);
            }

            if (_classes.IsValueCreated && _classes.Value.Count > 0)
            {
                if (subscribe)
                {
                    var observable = Observable.FromEventPattern <
                        NotifyCollectionChangedEventHandler,
                        NotifyCollectionChangedEventArgs>(
                        x => control.Classes.CollectionChanged += x,
                        x => control.Classes.CollectionChanged -= x)
                                     .StartWith((EventPattern <NotifyCollectionChangedEventArgs>)null)
                                     .Select(_ => Matches(control.Classes))
                                     .DistinctUntilChanged();
                    return(new SelectorMatch(observable));
                }
                else
                {
                    return(new SelectorMatch(Matches(control.Classes)));
                }
            }
            else
            {
                return(SelectorMatch.True);
            }
        }
Пример #35
0
        public void Attach(IStyleable control)
        {
            var description = "Style " + this.Selector.ToString();
            var match = this.Selector.Match(control);

            if (match.ImmediateResult.HasValue)
            {
                if (match.ImmediateResult == true)
                {
                    foreach (Setter setter in this.Setters)
                    {
                        if (setter.Source != null && setter.Value != null)
                        {
                            throw new InvalidOperationException("Cannot set both Source and Value on a Setter.");
                        }

                        if (setter.Source == null)
                        {
                            control.SetValue(setter.Property, setter.Value, BindingPriority.Style);
                        }
                        else
                        {
                            control.Bind(setter.Property, setter.Source, BindingPriority.Style);
                        }
                    }
                }
            }
            else
            {
                foreach (Setter setter in this.Setters)
                {
                    if (setter.Source != null && setter.Value != null)
                    {
                        throw new InvalidOperationException("Cannot set both Source and Value on a Setter.");
                    }

                    StyleBinding binding;

                    if (setter.Source == null)
                    {
                        binding = new StyleBinding(match.ObservableResult, setter.Value, description);
                    }
                    else
                    {
                        binding = new StyleBinding(match.ObservableResult, setter.Source, description);
                    }

                    control.Bind(setter.Property, binding, BindingPriority.StyleTrigger);
                }
            }
        }
Пример #36
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);
            }
        }
Пример #37
0
        private void ApplyStyles(IStyleable target, IStyleHost host)
        {
            var parent = host.StylingParent;

            if (parent != null)
            {
                ApplyStyles(target, parent);
            }

            if (host.IsStylesInitialized)
            {
                host.Styles.TryAttach(target, host);
            }
        }
Пример #38
0
        /// <summary>
        /// Applies the given style(s) to the given control.
        /// </summary>
        /// <param name="control">The control to apply the style(s) to.</param>
        /// <param name="styleHost">The style set to apply.</param>
        private void ApplyStyles(IStyleable control, IStyleHost styleHost)
        {
            Contract.Requires <ArgumentNullException>(control != null);
            Contract.Requires <ArgumentNullException>(styleHost != null);

            var parentContainer = styleHost.StylingParent;

            if (parentContainer != null)
            {
                ApplyStyles(control, parentContainer);
            }

            styleHost.Styles.Attach(control, styleHost);
        }
Пример #39
0
        /// <summary>
        /// Applies the setter to a control.
        /// </summary>
        /// <param name="style">The style that is being applied.</param>
        /// <param name="control">The control.</param>
        /// <param name="activator">An optional activator.</param>
        public IDisposable Apply(IStyle style, IStyleable control, IObservable<bool> activator)
        {
            Contract.Requires<ArgumentNullException>(control != null);

            var description = style?.ToString();

            if (Property == null)
            {
                throw new InvalidOperationException("Setter.Property must be set.");
            }

            var value = Value;
            var binding = value as IBinding;

            if (binding == null)
            {
                var template = value as ITemplate;
                bool isPropertyOfTypeITemplate = typeof(ITemplate).GetTypeInfo()
                    .IsAssignableFrom(Property.PropertyType.GetTypeInfo());

                if (template != null && !isPropertyOfTypeITemplate)
                {
                    var materialized = template.Build();
                    NameScope.SetNameScope((Visual)materialized, new NameScope());
                    value = materialized;
                }

                if (activator == null)
                {
                    return control.Bind(Property, ObservableEx.SingleValue(value), BindingPriority.Style);
                }
                else
                {
                    var activated = new ActivatedValue(activator, value, description);
                    return control.Bind(Property, activated, BindingPriority.StyleTrigger);
                }
            }
            else
            {
                var source = binding.Initiate(control, Property);

                if (source != null)
                {
                    var cloned = Clone(source, style, activator);
                    return BindingOperations.Apply(control, Property, cloned, null);
                }
            }

            return Disposable.Empty;
        }
Пример #40
0
        /// <summary>
        /// Applies the setter to a control.
        /// </summary>
        /// <param name="style">The style that is being applied.</param>
        /// <param name="control">The control.</param>
        /// <param name="activator">An optional activator.</param>
        public IDisposable Apply(IStyle style, IStyleable control, IObservable <bool> activator)
        {
            Contract.Requires <ArgumentNullException>(control != null);

            var description = style?.ToString();

            if (Property == null)
            {
                throw new InvalidOperationException("Setter.Property must be set.");
            }

            var value   = Value;
            var binding = value as IBinding;

            if (binding == null)
            {
                var  template = value as ITemplate;
                bool isPropertyOfTypeITemplate = typeof(ITemplate).GetTypeInfo()
                                                 .IsAssignableFrom(Property.PropertyType.GetTypeInfo());

                if (template != null && !isPropertyOfTypeITemplate)
                {
                    var materialized = template.Build();
                    NameScope.SetNameScope((Visual)materialized, new NameScope());
                    value = materialized;
                }

                if (activator == null)
                {
                    return(control.Bind(Property, ObservableEx.SingleValue(value), BindingPriority.Style));
                }
                else
                {
                    var activated = new ActivatedValue(activator, value, description);
                    return(control.Bind(Property, activated, BindingPriority.StyleTrigger));
                }
            }
            else
            {
                var source = binding.Initiate(control, Property);

                if (source != null)
                {
                    var cloned = Clone(source, style, activator);
                    return(BindingOperations.Apply(control, Property, cloned, null));
                }
            }

            return(Disposable.Empty);
        }
Пример #41
0
        private void ApplyStyles(IStyleable control, IStyleHost styleHost)
        {
            Contract.Requires<ArgumentNullException>(control != null);
            Contract.Requires<ArgumentNullException>(styleHost != null);

            var parentContainer = styleHost.StylingParent;

            if (parentContainer != null)
            {
                ApplyStyles(control, parentContainer);
            }

            styleHost.Styles.Attach(control, styleHost);
        }
Пример #42
0
        private static SelectorMatch MatchUntilCombinator(
            IStyleable control,
            Selector start,
            bool subscribe,
            out Selector?combinator)
        {
            combinator = null;

            var activators = new AndActivatorBuilder();
            var result     = Match(control, start, subscribe, ref activators, ref combinator);

            return(result == SelectorMatchResult.Sometimes ?
                   new SelectorMatch(activators.Get()) :
                   new SelectorMatch(result));
        }
Пример #43
0
 /// <inheritdoc/>
 protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
 {
     if (!AvaloniaPropertyRegistry.Instance.IsRegistered(control, _property))
     {
         return SelectorMatch.False;
     }
     else if (subscribe)
     {
         return new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v, _value)));
     }
     else
     {
         return new SelectorMatch(control.GetValue(_property).Equals(_value));
     }
 }
Пример #44
0
 /// <inheritdoc/>
 protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
 {
     if (!PerspexPropertyRegistry.Instance.IsRegistered(control, _property))
     {
         return(SelectorMatch.False);
     }
     else if (subscribe)
     {
         return(new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v, _value))));
     }
     else
     {
         return(new SelectorMatch(control.GetValue(_property).Equals(_value)));
     }
 }
Пример #45
0
        public void ApplyStyles(IStyleable control)
        {
            IVisual visual = control as IVisual;
            IStyleHost styleContainer = visual
                .GetSelfAndVisualAncestors()
                .OfType<IStyleHost>()
                .FirstOrDefault();
            IGlobalStyles global = PerspexLocator.Current.GetService<IGlobalStyles>();

            global?.Styles.Attach(control, null);

            if (styleContainer != null)
            {
                ApplyStyles(control, styleContainer);
            }
        }
Пример #46
0
        private void ApplyStyles(IStyleable control, IStyleHost container)
        {
            Contract.Requires<ArgumentNullException>(control != null);
            Contract.Requires<ArgumentNullException>(container != null);

            IVisual visual = container as IVisual;

            if (visual != null)
            {
                IStyleHost parentContainer = visual
                    .GetVisualAncestors()
                    .OfType<IStyleHost>()
                    .FirstOrDefault();

                if (parentContainer != null)
                {
                    ApplyStyles(control, parentContainer);
                }
            }

            container.Styles.Attach(control, container);
        }
Пример #47
0
        /// <summary>
        /// Applies the setter to the control.
        /// </summary>
        /// <param name="style">The style that is being applied.</param>
        /// <param name="control">The control.</param>
        /// <param name="activator">An optional activator.</param>
        public void Apply(IStyle style, IStyleable control, IObservable<bool> activator)
        {
            Contract.Requires<ArgumentNullException>(control != null);

            var description = style?.ToString();

            if (Property == null)
            {
                throw new InvalidOperationException("Setter.Property must be set.");
            }

            var binding = Value as IBinding;

            if (binding != null)
            {
                if (activator == null)
                {
                    control.Bind(Property, binding);
                }
                else
                {
                    var subject = binding.CreateSubject(control, Property);
                    var activated = new ActivatedSubject(activator, subject, description);
                    Bind(control, Property, binding, activated);
                }
            }
            else
            {
                if (activator == null)
                {
                    control.SetValue(Property, Value, BindingPriority.Style);
                }
                else
                {
                    var activated = new ActivatedValue(activator, Value, description);
                    control.Bind(Property, activated, BindingPriority.StyleTrigger);
                }
            }
        }
Пример #48
0
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            ILogical c = (ILogical)control;
            List<IObservable<bool>> descendentMatches = 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
                    {
                        descendentMatches.Add(match.ObservableResult);
                    }
                }
            }

            if (descendentMatches.Count > 0)
            {
                return new SelectorMatch(StyleActivator.Or(descendentMatches));
            }
            else
            {
                return SelectorMatch.False;
            }
        }
Пример #49
0
        /// <summary>
        /// Called when a control's <see cref="IStyleable.StyleDetach"/> is signalled to remove
        /// all applied styles.
        /// </summary>
        /// <param name="control">The control.</param>
        private static void ControlDetach(IStyleable control)
        {
            var subscriptions = _applied[control];

            foreach (var subscription in subscriptions)
            {
                subscription.Dispose();
            }

            _applied.Remove(control);
        }
Пример #50
0
        private static List<IDisposable> GetSubscriptions(IStyleable control)
        {
            List<IDisposable> subscriptions;

            if (!_applied.TryGetValue(control, out subscriptions))
            {
                subscriptions = new List<IDisposable>(2);
                subscriptions.Add(control.StyleDetach.Subscribe(ControlDetach));
                _applied.Add(control, subscriptions);
            }

            return subscriptions;
        }
        /// <inheritdoc/>
        protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
        {
            if (TargetType != null)
            {
                var controlType = control.StyleKey ?? control.GetType();

                if (IsConcreteType)
                {
                    if (controlType != TargetType)
                    {
                        return SelectorMatch.False;
                    }
                }
                else
                {
                    if (!TargetType.GetTypeInfo().IsAssignableFrom(controlType.GetTypeInfo()))
                    {
                        return SelectorMatch.False;
                    }
                }
            }

            if (Name != null && control.Name != Name)
            {
                return SelectorMatch.False;
            }

            if (_classes.IsValueCreated && _classes.Value.Count > 0)
            {
                if (subscribe)
                {
                    var observable = Observable.FromEventPattern<
                            NotifyCollectionChangedEventHandler,
                            NotifyCollectionChangedEventArgs>(
                        x => control.Classes.CollectionChanged += x,
                        x => control.Classes.CollectionChanged -= x)
                        .StartWith((EventPattern<NotifyCollectionChangedEventArgs>)null)
                        .Select(_ => Matches(control.Classes));
                    return new SelectorMatch(observable);
                }
                else
                {
                    return new SelectorMatch(Matches(control.Classes));
                }
            }
            else
            {
                return SelectorMatch.True;
            }
        }
Пример #52
0
        private void Bind(
            IStyleable control,
            PerspexProperty property,
            IBinding binding,
            ISubject<object> subject)
        {
            var mode = binding.Mode;

            if (mode == BindingMode.Default)
            {
                mode = property.GetMetadata(control.GetType()).DefaultBindingMode;
            }

            control.Bind(
                property,
                subject,
                mode,
                binding.Priority);
        }
Пример #53
0
 /// <summary>
 /// Evaluates the selector for a match.
 /// </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>
 protected abstract SelectorMatch Evaluate(IStyleable control, bool subscribe);