using System; namespace Avalonia.Styling { /// /// Defines a style. /// public class Style : StyleBase { private Selector? _selector; /// /// Initializes a new instance of the class. /// public Style() { } /// /// Initializes a new instance of the class. /// /// The style selector. public Style(Func selector) { Selector = selector(null); } /// /// Gets or sets the style's selector. /// public Selector? Selector { get => _selector; set => _selector = ValidateSelector(value); } /// /// Returns a string representation of the style. /// /// A string representation of the style. public override string ToString() => Selector?.ToString(this) ?? "Style"; internal override void SetParent(StyleBase? parent) { if (parent is Style parentStyle && parentStyle.Selector is not null) { if (Selector is null) throw new InvalidOperationException("Child styles must have a selector."); Selector.ValidateNestingSelector(false); } else if (parent is ControlTheme) { if (Selector is null) throw new InvalidOperationException("Child styles must have a selector."); Selector.ValidateNestingSelector(true); } base.SetParent(parent); } internal override SelectorMatchResult TryAttach(IStyleable target, object? host) { _ = target ?? throw new ArgumentNullException(nameof(target)); var result = SelectorMatchResult.NeverThisType; if (HasSettersOrAnimations) { var match = Selector?.Match(target, Parent, true) ?? (target == host ? SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance); if (match.IsMatch) { Attach(target, match.Activator); } result = match.Result; } return result; } private static Selector? ValidateSelector(Selector? selector) { if (selector is TemplateSelector) throw new InvalidOperationException( "Invalid selector: Template selector must be followed by control selector."); return selector; } } }