diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs index 2f3f672d54..c72f398fd9 100644 --- a/src/Avalonia.Base/StyledElement.cs +++ b/src/Avalonia.Base/StyledElement.cs @@ -355,22 +355,19 @@ namespace Avalonia { if (_initCount == 0 && !_styled) { - var styler = AvaloniaLocator.Current.GetService(); var hasPromotedTheme = _hasPromotedTheme; - if (styler is object) - { - GetValueStore().BeginStyling(); + GetValueStore().BeginStyling(); - try - { - styler.ApplyStyles(this); - } - finally - { - _styled = true; - GetValueStore().EndStyling(); - } + try + { + ApplyControlTheme(); + ApplyStyles(this); + } + finally + { + _styled = true; + GetValueStore().EndStyling(); } if (hasPromotedTheme) @@ -509,31 +506,6 @@ namespace Avalonia }; } - ControlTheme? IStyleable.GetEffectiveTheme() - { - var theme = Theme; - - // Explitly set Theme property takes precedence. - if (theme is not null) - return theme; - - // If the Theme property is not set, try to find a ControlTheme resource with our StyleKey. - if (_implicitTheme is null) - { - var key = ((IStyleable)this).StyleKey; - - if (this.TryFindResource(key, out var value) && value is ControlTheme t) - _implicitTheme = t; - else - _implicitTheme = s_invalidTheme; - } - - if (_implicitTheme != s_invalidTheme) - return _implicitTheme; - - return null; - } - void IStyleable.DetachStyles() => DetachStyles(); void IStyleHost.StylesAdded(IReadOnlyList styles) @@ -670,6 +642,31 @@ namespace Avalonia { } + internal ControlTheme? GetEffectiveTheme() + { + var theme = Theme; + + // Explitly set Theme property takes precedence. + if (theme is not null) + return theme; + + // If the Theme property is not set, try to find a ControlTheme resource with our StyleKey. + if (_implicitTheme is null) + { + var key = ((IStyleable)this).StyleKey; + + if (this.TryFindResource(key, out var value) && value is ControlTheme t) + _implicitTheme = t; + else + _implicitTheme = s_invalidTheme; + } + + if (_implicitTheme != s_invalidTheme) + return _implicitTheme; + + return null; + } + private static void DataContextNotifying(IAvaloniaObject o, bool updateStarted) { if (o is StyledElement element) @@ -734,6 +731,56 @@ namespace Avalonia } } + private void ApplyControlTheme() + { + var theme = GetEffectiveTheme(); + + if (theme is not null) + ApplyControlTheme(theme); + + if (TemplatedParent is StyledElement styleableParent && + styleableParent.GetEffectiveTheme() is { } parentTheme) + { + ApplyControlTheme(parentTheme); + } + } + + private void ApplyControlTheme(ControlTheme theme) + { + if (theme.BasedOn is ControlTheme basedOn) + ApplyControlTheme(basedOn); + + theme.TryAttach(this, null); + + if (theme.HasChildren) + { + foreach (var child in theme.Children) + ApplyStyle(child, null); + } + } + + private void ApplyStyles(IStyleHost host) + { + var parent = host.StylingParent; + if (parent != null) + ApplyStyles(parent); + + if (host.IsStylesInitialized) + { + foreach (var style in host.Styles) + ApplyStyle(style, host); + } + } + + private void ApplyStyle(IStyle style, IStyleHost? host) + { + if (style is Style s) + s.TryAttach(this, host); + + foreach (var child in style.Children) + ApplyStyle(child, host); + } + private void OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) { if (this.GetLogicalParent() == null && !(this is ILogicalRoot)) diff --git a/src/Avalonia.Base/Styling/ControlTheme.cs b/src/Avalonia.Base/Styling/ControlTheme.cs index 46a3267f70..2971703c95 100644 --- a/src/Avalonia.Base/Styling/ControlTheme.cs +++ b/src/Avalonia.Base/Styling/ControlTheme.cs @@ -29,34 +29,27 @@ namespace Avalonia.Styling /// public ControlTheme? BasedOn { get; set; } - public override SelectorMatchResult TryAttach(IStyleable target, object? host) + public override string ToString() => TargetType?.Name ?? "ControlTheme"; + + internal override void SetParent(StyleBase? parent) + { + throw new InvalidOperationException("ControlThemes cannot be added as a nested style."); + } + + internal override SelectorMatchResult TryAttach(IStyleable target, object? host) { _ = target ?? throw new ArgumentNullException(nameof(target)); if (TargetType is null) throw new InvalidOperationException("ControlTheme has no TargetType."); - var result = BasedOn?.TryAttach(target, host) ?? SelectorMatchResult.NeverThisType; - if (HasSettersOrAnimations && TargetType.IsAssignableFrom(target.StyleKey)) { Attach(target, null); - result = SelectorMatchResult.AlwaysThisType; + return SelectorMatchResult.AlwaysThisType; } - var childResult = TryAttachChildren(target, host); - - if (childResult > result) - result = childResult; - - return result; - } - - public override string ToString() => TargetType?.Name ?? "ControlTheme"; - - internal override void SetParent(StyleBase? parent) - { - throw new InvalidOperationException("ControlThemes cannot be added as a nested style."); + return SelectorMatchResult.NeverThisType; } } } diff --git a/src/Avalonia.Base/Styling/IStyle.cs b/src/Avalonia.Base/Styling/IStyle.cs index 417739fb28..2dbaf963ee 100644 --- a/src/Avalonia.Base/Styling/IStyle.cs +++ b/src/Avalonia.Base/Styling/IStyle.cs @@ -14,15 +14,5 @@ namespace Avalonia.Styling /// Gets a collection of child styles. /// IReadOnlyList Children { get; } - - /// - /// Attaches the style and any child styles to a control if the style's selector matches. - /// - /// The control to attach to. - /// The element that hosts the style. - /// - /// A describing how the style matches the control. - /// - SelectorMatchResult TryAttach(IStyleable target, object? host); } } diff --git a/src/Avalonia.Base/Styling/IStyleable.cs b/src/Avalonia.Base/Styling/IStyleable.cs index e94fc5c4e6..dcc3988280 100644 --- a/src/Avalonia.Base/Styling/IStyleable.cs +++ b/src/Avalonia.Base/Styling/IStyleable.cs @@ -25,11 +25,6 @@ namespace Avalonia.Styling /// ITemplatedControl? TemplatedParent { get; } - /// - /// Gets the effective theme for the control as used by the syling system. - /// - ControlTheme? GetEffectiveTheme(); - void DetachStyles(); } } diff --git a/src/Avalonia.Base/Styling/IStyler.cs b/src/Avalonia.Base/Styling/IStyler.cs deleted file mode 100644 index d6477d169e..0000000000 --- a/src/Avalonia.Base/Styling/IStyler.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace Avalonia.Styling -{ - public interface IStyler - { - void ApplyStyles(IStyleable control); - } -} diff --git a/src/Avalonia.Base/Styling/Style.cs b/src/Avalonia.Base/Styling/Style.cs index 913c437bc4..aad91824d3 100644 --- a/src/Avalonia.Base/Styling/Style.cs +++ b/src/Avalonia.Base/Styling/Style.cs @@ -1,5 +1,4 @@ using System; -using Avalonia.PropertyStore; namespace Avalonia.Styling { @@ -35,35 +34,6 @@ namespace Avalonia.Styling set => _selector = ValidateSelector(value); } - public 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; - } - - var childResult = TryAttachChildren(target, host); - - if (childResult > result) - result = childResult; - - return result; - } - /// /// Returns a string representation of the style. /// @@ -88,6 +58,30 @@ namespace Avalonia.Styling 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) diff --git a/src/Avalonia.Base/Styling/StyleBase.cs b/src/Avalonia.Base/Styling/StyleBase.cs index c914fbf8cc..dba80df2e5 100644 --- a/src/Avalonia.Base/Styling/StyleBase.cs +++ b/src/Avalonia.Base/Styling/StyleBase.cs @@ -18,7 +18,6 @@ namespace Avalonia.Styling private IResourceDictionary? _resources; private List? _setters; private List? _animations; - private StyleCache? _childCache; private StyleInstance? _sharedInstance; public IList Children => _children ??= new(this); @@ -67,6 +66,7 @@ namespace Avalonia.Styling bool IResourceNode.HasResources => _resources?.Count > 0; IReadOnlyList IStyle.Children => (IReadOnlyList?)_children ?? Array.Empty(); + internal bool HasChildren => _children?.Count > 0; internal bool HasSettersOrAnimations => _setters?.Count > 0 || _animations?.Count > 0; public void Add(ISetter setter) => Setters.Add(setter); @@ -74,14 +74,26 @@ namespace Avalonia.Styling public event EventHandler? OwnerChanged; - public abstract SelectorMatchResult TryAttach(IStyleable target, object? host); - public bool TryGetResource(object key, out object? result) { - result = null; - return _resources?.TryGetResource(key, out result) ?? false; + if (_resources is not null && _resources.TryGetResource(key, out result)) + return true; + + if (_children is not null) + { + for (var i = 0; i < _children.Count; ++i) + { + if (_children[i].TryGetResource(key, out result)) + return true; + } + } + + result= null; + return false; } + internal abstract SelectorMatchResult TryAttach(IStyleable target, object? host); + internal ValueFrame Attach(IStyleable target, IStyleActivator? activator) { if (target is not AvaloniaObject ao) @@ -124,14 +136,6 @@ namespace Avalonia.Styling return instance; } - internal SelectorMatchResult TryAttachChildren(IStyleable target, object? host) - { - if (_children is null || _children.Count == 0) - return SelectorMatchResult.NeverThisType; - _childCache ??= new StyleCache(); - return _childCache.TryAttach(_children, target, host); - } - internal virtual void SetParent(StyleBase? parent) => Parent = parent; void IResourceProvider.AddOwner(IResourceHost owner) diff --git a/src/Avalonia.Base/Styling/StyleCache.cs b/src/Avalonia.Base/Styling/StyleCache.cs deleted file mode 100644 index 81196f6a27..0000000000 --- a/src/Avalonia.Base/Styling/StyleCache.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Avalonia.Styling -{ - /// - /// Simple cache for improving performance of applying styles. - /// - /// - /// Maps to a list of styles that are known be be possible - /// matches. - /// - internal class StyleCache : Dictionary?> - { - public SelectorMatchResult TryAttach(IList styles, IStyleable target, object? host) - { - if (TryGetValue(target.StyleKey, out var cached)) - { - if (cached is object) - { - var result = SelectorMatchResult.NeverThisType; - - foreach (var style in cached) - { - var childResult = style.TryAttach(target, host); - if (childResult > result) - result = childResult; - } - - return result; - } - else - { - return SelectorMatchResult.NeverThisType; - } - } - else - { - List? matches = null; - - foreach (var child in styles) - { - if (child.TryAttach(target, host) != SelectorMatchResult.NeverThisType) - { - matches ??= new List(); - matches.Add(child); - } - } - - Add(target.StyleKey, matches); - - return matches is null ? - SelectorMatchResult.NeverThisType : - SelectorMatchResult.AlwaysThisType; - } - } - } -} diff --git a/src/Avalonia.Base/Styling/Styler.cs b/src/Avalonia.Base/Styling/Styler.cs deleted file mode 100644 index ad5c1cd102..0000000000 --- a/src/Avalonia.Base/Styling/Styler.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace Avalonia.Styling -{ - public class Styler : IStyler - { - public void ApplyStyles(IStyleable target) - { - _ = target ?? throw new ArgumentNullException(nameof(target)); - - // Apply the control theme. - target.GetEffectiveTheme()?.TryAttach(target, target); - - // If the control has a themed templated parent then apply the styles from the - // templated parent theme. - if (target.TemplatedParent is IStyleable styleableParent) - styleableParent.GetEffectiveTheme()?.TryAttach(target, styleableParent); - - // Apply styles from the rest of the tree. - if (target is IStyleHost styleHost) - ApplyStyles(target, styleHost); - } - - 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); - } - } -} diff --git a/src/Avalonia.Base/Styling/Styles.cs b/src/Avalonia.Base/Styling/Styles.cs index c213475bb7..76271b9748 100644 --- a/src/Avalonia.Base/Styling/Styles.cs +++ b/src/Avalonia.Base/Styling/Styles.cs @@ -5,8 +5,6 @@ using System.Collections.Specialized; using Avalonia.Collections; using Avalonia.Controls; -#nullable enable - namespace Avalonia.Styling { /// @@ -20,7 +18,6 @@ namespace Avalonia.Styling private readonly AvaloniaList _styles = new(); private IResourceHost? _owner; private IResourceDictionary? _resources; - private StyleCache? _cache; public Styles() { @@ -116,12 +113,6 @@ namespace Avalonia.Styling set => _styles[index] = value; } - public SelectorMatchResult TryAttach(IStyleable target, object? host) - { - _cache ??= new StyleCache(); - return _cache.TryAttach(this, target, host); - } - /// public bool TryGetResource(object key, out object? value) { @@ -234,6 +225,22 @@ namespace Avalonia.Styling } } + internal SelectorMatchResult TryAttach(IStyleable target, object? host) + { + var result = SelectorMatchResult.NeverThisType; + + foreach (var s in this) + { + if (s is not Style style) + continue; + var r = style.TryAttach(target, host); + if (r > result) + result = r; + } + + return result; + } + private static IReadOnlyList ToReadOnlyList(ICollection list) { if (list is IReadOnlyList readOnlyList) @@ -246,7 +253,7 @@ namespace Avalonia.Styling return result; } - private static void InternalAdd(IList items, IResourceHost? owner, ref StyleCache? cache) + private static void InternalAdd(IList items, IResourceHost? owner) { if (owner is not null) { @@ -260,14 +267,9 @@ namespace Avalonia.Styling (owner as IStyleHost)?.StylesAdded(ToReadOnlyList(items)); } - - if (items.Count > 0) - { - cache = null; - } } - private static void InternalRemove(IList items, IResourceHost? owner, ref StyleCache? cache) + private static void InternalRemove(IList items, IResourceHost? owner) { if (owner is not null) { @@ -281,11 +283,6 @@ namespace Avalonia.Styling (owner as IStyleHost)?.StylesRemoved(ToReadOnlyList(items)); } - - if (items.Count > 0) - { - cache = null; - } } private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -300,14 +297,14 @@ namespace Avalonia.Styling switch (e.Action) { case NotifyCollectionChangedAction.Add: - InternalAdd(e.NewItems!, currentOwner, ref _cache); + InternalAdd(e.NewItems!, currentOwner); break; case NotifyCollectionChangedAction.Remove: - InternalRemove(e.OldItems!, currentOwner, ref _cache); + InternalRemove(e.OldItems!, currentOwner); break; case NotifyCollectionChangedAction.Replace: - InternalRemove(e.OldItems!, currentOwner, ref _cache); - InternalAdd(e.NewItems!, currentOwner, ref _cache); + InternalRemove(e.OldItems!, currentOwner); + InternalAdd(e.NewItems!, currentOwner); break; } diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 69fd6cabf8..dc9a0207ad 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -39,7 +39,6 @@ namespace Avalonia private readonly Lazy _clipboard = new Lazy(() => (IClipboard?)AvaloniaLocator.Current.GetService(typeof(IClipboard))); - private readonly Styler _styler = new Styler(); private Styles? _styles; private IResourceDictionary? _resources; private bool _notifyingResourcesChanged; @@ -232,7 +231,6 @@ namespace Avalonia .Bind().ToConstant(FocusManager) .Bind().ToConstant(InputManager) .Bind().ToTransient() - .Bind().ToConstant(_styler) .Bind().ToConstant(AvaloniaScheduler.Instance) .Bind().ToConstant(DragDropDevice.Instance); diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 6804c9ecb9..515535bf39 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -145,7 +145,6 @@ namespace Avalonia.Controls _actualTransparencyLevel = PlatformImpl.TransparencyLevel; dependencyResolver = dependencyResolver ?? AvaloniaLocator.Current; - var styler = TryGetService(dependencyResolver); _accessKeyHandler = TryGetService(dependencyResolver); _inputManager = TryGetService(dependencyResolver); @@ -183,7 +182,7 @@ namespace Avalonia.Controls _globalStyles.GlobalStylesRemoved += ((IStyleHost)this).StylesRemoved; } - styler?.ApplyStyles(this); + ApplyStyling(); ClientSize = impl.ClientSize; FrameSize = impl.FrameSize; diff --git a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs index b1725245bb..8af49b5480 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs @@ -82,8 +82,6 @@ namespace Avalonia.Markup.Xaml.Styling } } - public SelectorMatchResult TryAttach(IStyleable target, object? host) => Loaded.TryAttach(target, host); - public bool TryGetResource(object key, out object? value) { if (!_isLoading) diff --git a/tests/Avalonia.Base.UnitTests/Animation/AnimatableTests.cs b/tests/Avalonia.Base.UnitTests/Animation/AnimatableTests.cs index 19ae0dc260..668b8a875c 100644 --- a/tests/Avalonia.Base.UnitTests/Animation/AnimatableTests.cs +++ b/tests/Avalonia.Base.UnitTests/Animation/AnimatableTests.cs @@ -498,7 +498,7 @@ namespace Avalonia.Base.UnitTests.Animation private static IDisposable Start() { var clock = new MockGlobalClock(); - var services = TestServices.RealStyler.With(globalClock: clock); + var services = new TestServices(globalClock: clock); return UnitTestApplication.Start(services); } diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs b/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs index b7455f9b3f..e7ecba61a7 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs @@ -5,7 +5,6 @@ using Avalonia.Base.UnitTests.Animation; using Avalonia.Controls; using Avalonia.Controls.Templates; using Avalonia.Data; -using Avalonia.Diagnostics; using Avalonia.Styling; using Avalonia.UnitTests; using Moq; @@ -301,8 +300,6 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Inactive_Values_Should_Not_Be_Made_Active_During_Style_Attach() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var root = new TestRoot { Styles = @@ -337,8 +334,6 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Inactive_Bindings_Should_Not_Be_Made_Active_During_Style_Attach() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var root = new TestRoot { Styles = @@ -380,8 +375,6 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Inactive_Values_Should_Not_Be_Made_Active_During_Style_Detach() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var root = new TestRoot { Styles = @@ -417,8 +410,6 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Inactive_Values_Should_Not_Be_Made_Active_During_Style_Detach_2() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var root = new TestRoot { Styles = @@ -454,8 +445,6 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Inactive_Bindings_Should_Not_Be_Made_Active_During_Style_Detach() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var root = new TestRoot { Styles = @@ -598,41 +587,36 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Removing_Style_Should_Detach_From_Control() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var border = new Border(); + var root = new TestRoot { - var border = new Border(); - var root = new TestRoot - { - Styles = - { - new Style(x => x.OfType()) + Styles = + { + new Style(x => x.OfType()) + { + Setters = { - Setters = - { - new Setter(Border.BorderThicknessProperty, new Thickness(4)), - } + new Setter(Border.BorderThicknessProperty, new Thickness(4)), } - }, - Child = border, - }; + } + }, + Child = border, + }; - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(4), border.BorderThickness); + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(4), border.BorderThickness); - root.Styles.RemoveAt(0); - Assert.Equal(new Thickness(0), border.BorderThickness); - } + root.Styles.RemoveAt(0); + Assert.Equal(new Thickness(0), border.BorderThickness); } [Fact] public void Adding_Style_Should_Attach_To_Control() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var border = new Border(); + var root = new TestRoot { - var border = new Border(); - var root = new TestRoot - { - Styles = + Styles = { new Style(x => x.OfType()) { @@ -642,34 +626,31 @@ namespace Avalonia.Base.UnitTests.Styling } } }, - Child = border, - }; + Child = border, + }; - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(4), border.BorderThickness); + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(4), border.BorderThickness); - root.Styles.Add(new Style(x => x.OfType()) - { - Setters = + root.Styles.Add(new Style(x => x.OfType()) + { + Setters = { new Setter(Border.BorderThicknessProperty, new Thickness(6)), } - }); + }); - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(6), border.BorderThickness); - } + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(6), border.BorderThickness); } [Fact] public void Removing_Style_With_Nested_Style_Should_Detach_From_Control() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var border = new Border(); + var root = new TestRoot { - var border = new Border(); - var root = new TestRoot - { - Styles = + Styles = { new Styles { @@ -682,96 +663,89 @@ namespace Avalonia.Base.UnitTests.Styling } } }, - Child = border, - }; + Child = border, + }; - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(4), border.BorderThickness); + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(4), border.BorderThickness); - root.Styles.RemoveAt(0); - Assert.Equal(new Thickness(0), border.BorderThickness); - } + root.Styles.RemoveAt(0); + Assert.Equal(new Thickness(0), border.BorderThickness); } - + [Fact] public void Adding_Nested_Style_Should_Attach_To_Control() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var border = new Border(); + var root = new TestRoot { - var border = new Border(); - var root = new TestRoot + Styles = { - Styles = + new Styles { - new Styles + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter(Border.BorderThicknessProperty, new Thickness(4)), - } + new Setter(Border.BorderThicknessProperty, new Thickness(4)), } } - }, - Child = border, - }; + } + }, + Child = border, + }; - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(4), border.BorderThickness); + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(4), border.BorderThickness); - ((Styles)root.Styles[0]).Add(new Style(x => x.OfType()) + ((Styles)root.Styles[0]).Add(new Style(x => x.OfType()) + { + Setters = { - Setters = - { - new Setter(Border.BorderThicknessProperty, new Thickness(6)), - } - }); + new Setter(Border.BorderThicknessProperty, new Thickness(6)), + } + }); - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(6), border.BorderThickness); - } + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(6), border.BorderThickness); } [Fact] public void Removing_Nested_Style_Should_Detach_From_Control() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var border = new Border(); + var root = new TestRoot { - var border = new Border(); - var root = new TestRoot + Styles = { - Styles = + new Styles { - new Styles + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter(Border.BorderThicknessProperty, new Thickness(4)), - } - }, - new Style(x => x.OfType()) + new Setter(Border.BorderThicknessProperty, new Thickness(4)), + } + }, + new Style(x => x.OfType()) + { + Setters = { - Setters = - { - new Setter(Border.BorderThicknessProperty, new Thickness(6)), - } - }, - } - }, - Child = border, - }; + new Setter(Border.BorderThicknessProperty, new Thickness(6)), + } + }, + } + }, + Child = border, + }; - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(6), border.BorderThickness); + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(6), border.BorderThickness); - ((Styles)root.Styles[0]).RemoveAt(1); + ((Styles)root.Styles[0]).RemoveAt(1); - root.Measure(Size.Infinity); - Assert.Equal(new Thickness(4), border.BorderThickness); - } + root.Measure(Size.Infinity); + Assert.Equal(new Thickness(4), border.BorderThickness); } [Fact] diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests.cs b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests.cs index c01e22347b..65fe50b545 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests.cs @@ -249,65 +249,67 @@ namespace Avalonia.Base.UnitTests.Styling } [Fact] - public void Adding_Tree_To_IStyleRoot_Should_Style_Controls() + public void Adding_Tree_To_Root_Should_Style_Controls() { - using (AvaloniaLocator.EnterScope()) + var root = new TestRoot { - var root = new TestRoot(); - var parent = new Border(); - var child = new Border(); - var grandchild = new Control(); - var styler = new Mock(); - - AvaloniaLocator.CurrentMutable.Bind().ToConstant(styler.Object); + Styles = + { + new Style(x => x.Is()) + { + Setters = { new Setter(Control.TagProperty, "foo") } + } + } + }; - parent.Child = child; - child.Child = grandchild; + var grandchild = new Control(); + var child = new Border { Child = grandchild }; + var parent = new Border { Child = child }; - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Never()); + Assert.Null(parent.Tag); + Assert.Null(child.Tag); + Assert.Null(grandchild.Tag); - root.Child = parent; + root.Child = parent; - styler.Verify(x => x.ApplyStyles(parent), Times.Once()); - styler.Verify(x => x.ApplyStyles(child), Times.Once()); - styler.Verify(x => x.ApplyStyles(grandchild), Times.Once()); - } + Assert.Equal("foo", parent.Tag); + Assert.Equal("foo", child.Tag); + Assert.Equal("foo", grandchild.Tag); } [Fact] public void Styles_Not_Applied_Until_Initialization_Finished() { - using (AvaloniaLocator.EnterScope()) + var root = new TestRoot { - var root = new TestRoot(); - var child = new Border(); - var styler = new Mock(); + Styles = + { + new Style(x => x.Is()) + { + Setters = { new Setter(Control.TagProperty, "foo") } + } + } + }; - AvaloniaLocator.CurrentMutable.Bind().ToConstant(styler.Object); + var child = new Border(); - ((ISupportInitialize)child).BeginInit(); - root.Child = child; - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Never()); + ((ISupportInitialize)child).BeginInit(); + root.Child = child; + Assert.Null(child.Tag); - ((ISupportInitialize)child).EndInit(); - styler.Verify(x => x.ApplyStyles(child), Times.Once()); - } + ((ISupportInitialize)child).EndInit(); + Assert.Equal("foo", child.Tag); } [Fact] public void Name_Cannot_Be_Set_After_Added_To_Logical_Tree() { - using (AvaloniaLocator.EnterScope()) - { - var root = new TestRoot(); - var child = new Border(); - - AvaloniaLocator.CurrentMutable.BindToSelf(new Styler()); + var root = new TestRoot(); + var child = new Border(); - root.Child = child; + root.Child = child; - Assert.Throws(() => child.Name = "foo"); - } + Assert.Throws(() => child.Name = "foo"); } [Fact] @@ -328,7 +330,7 @@ namespace Avalonia.Base.UnitTests.Styling [Fact] public void Style_Is_Removed_When_Control_Removed_From_Logical_Tree() { - var app = UnitTestApplication.Start(TestServices.RealStyler); + var app = UnitTestApplication.Start(); var target = new Border(); var root = new TestRoot { diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs index 45188de6cb..a1dac931ce 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs @@ -19,7 +19,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Applied_When_Attached_To_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); Assert.Null(target.Template); @@ -37,7 +36,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Applied_To_Derived_Class_When_Attached_To_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = new DerivedThemedControl { Theme = CreateTheme(), @@ -58,7 +56,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Detached_When_Theme_Property_Cleared() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); var root = CreateRoot(target); @@ -71,8 +68,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Detached_From_Template_Controls_When_Theme_Property_Cleared() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); - var theme = new ControlTheme { TargetType = typeof(ThemedControl), @@ -105,7 +100,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Applied_On_Layout_After_Theme_Property_Changes() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = new ThemedControl(); var root = CreateRoot(target); @@ -124,7 +118,6 @@ public class StyledElementTests_Theming [Fact] public void BasedOn_Theme_Is_Applied_When_Attached_To_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(CreateDerivedTheme()); Assert.Null(target.Template); @@ -163,7 +156,6 @@ public class StyledElementTests_Theming [Fact] public void Implicit_Theme_Is_Applied_When_Attached_To_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); var root = CreateRoot(target); Assert.NotNull(target.Template); @@ -178,21 +170,19 @@ public class StyledElementTests_Theming [Fact] public void Implicit_Theme_Is_Cleared_When_Removed_From_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); var root = CreateRoot(target); - Assert.NotNull(((IStyleable)target).GetEffectiveTheme()); + Assert.NotNull(target.GetEffectiveTheme()); root.Child = null; - Assert.Null(((IStyleable)target).GetEffectiveTheme()); + Assert.Null(target.GetEffectiveTheme()); } [Fact] public void Nested_Style_Can_Override_Property_In_Inner_Templated_Control() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = new ThemedControl2 { Theme = new ControlTheme(typeof(ThemedControl2)) @@ -236,7 +226,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Is_Applied_When_Attached_To_Logical_Tree() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); Assert.Null(target.Theme); @@ -248,16 +237,15 @@ public class StyledElementTests_Theming Assert.NotNull(target.Template); var border = Assert.IsType(target.VisualChild); - Assert.Equal(border.Background, Brushes.Red); + Assert.Equal(Brushes.Red, border.Background); target.Classes.Add("foo"); - Assert.Equal(border.Background, Brushes.Green); + Assert.Equal(Brushes.Green, border.Background); } [Fact] public void Theme_Can_Be_Changed_By_Style_Class() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); var theme1 = CreateTheme(); var theme2 = new ControlTheme(typeof(ThemedControl)); @@ -290,7 +278,6 @@ public class StyledElementTests_Theming [Fact] public void Theme_Can_Be_Set_To_LocalValue_While_Updating_Due_To_Style_Class() { - using var app = UnitTestApplication.Start(TestServices.RealStyler); var target = CreateTarget(); var theme1 = CreateTheme(); var theme2 = new ControlTheme(typeof(ThemedControl)); diff --git a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs index b16e891924..59953f457a 100644 --- a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs @@ -22,7 +22,6 @@ namespace Avalonia.Benchmarks.Styling platform: new AppBuilder().RuntimePlatform, renderInterface: new MockPlatformRenderInterface(), standardCursorFactory: Mock.Of(), - styler: new Styler(), theme: () => CreateTheme(), threadingInterface: new NullThreadingPlatform(), fontManagerImpl: new MockFontManagerImpl(), diff --git a/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs b/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs index ae874b8a61..1115bc9760 100644 --- a/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs +++ b/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs @@ -46,7 +46,6 @@ namespace Avalonia.Benchmarks.Themes platform: new AppBuilder().RuntimePlatform, renderInterface: new MockPlatformRenderInterface(), standardCursorFactory: Mock.Of(), - styler: new Styler(), theme: () => LoadFluentTheme(), threadingInterface: new NullThreadingPlatform(), fontManagerImpl: new MockFontManagerImpl(), diff --git a/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs b/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs index 7cc0bae97f..1e37093736 100644 --- a/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs @@ -37,11 +37,19 @@ namespace Avalonia.Controls.UnitTests [Fact] public void Templated_Children_Should_Be_Styled() { - var root = new TestRoot(); + var root = new TestRoot + { + Styles = + { + new Style(x => x.Is()) + { + Setters = { new Setter(Control.TagProperty, "foo") } + } + } + }; + var target = new ContentControl(); - var styler = new Mock(); - AvaloniaLocator.CurrentMutable.Bind().ToConstant(styler.Object); target.Content = "Foo"; target.Template = GetTemplate(); root.Child = target; @@ -49,10 +57,8 @@ namespace Avalonia.Controls.UnitTests target.ApplyTemplate(); target.Presenter.ApplyTemplate(); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); + foreach (Control child in target.GetTemplateChildren()) + Assert.Equal("foo", child.Tag); } [Fact] @@ -332,40 +338,37 @@ namespace Avalonia.Controls.UnitTests [Fact] public void Should_Set_Child_LogicalParent_After_Removing_And_Adding_Back_To_Logical_Tree() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var target = new ContentControl(); + var root = new TestRoot { - var target = new ContentControl(); - var root = new TestRoot + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter(ContentControl.TemplateProperty, GetTemplate()), - } + new Setter(ContentControl.TemplateProperty, GetTemplate()), } - }, - Child = target - }; + } + }, + Child = target + }; - target.Content = "Foo"; - target.ApplyTemplate(); - target.Presenter.ApplyTemplate(); + target.Content = "Foo"; + target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); - Assert.Equal(target, target.Presenter.Child.LogicalParent); + Assert.Equal(target, target.Presenter.Child.LogicalParent); - root.Child = null; + root.Child = null; - Assert.Null(target.Template); + Assert.Null(target.Template); - target.Content = null; - root.Child = target; - target.Content = "Bar"; + target.Content = null; + root.Child = target; + target.Content = "Bar"; - Assert.Equal(target, target.Presenter.Child.LogicalParent); - } + Assert.Equal(target, target.Presenter.Child.LogicalParent); } private FuncControlTemplate GetTemplate() diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs index f6d96edb99..7b7f0fcc98 100644 --- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs @@ -99,7 +99,7 @@ namespace Avalonia.Controls.UnitTests using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) { var items = new[] { "Foo", "Bar", "Baz " }; - var theme = new ControlTheme(); + var theme = new ControlTheme(typeof(ListBoxItem)); var target = new ListBox { Template = ListBoxTemplate(), @@ -121,7 +121,7 @@ namespace Avalonia.Controls.UnitTests using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) { var items = new[] { "Foo", "Bar", "Baz " }; - var theme = new ControlTheme(); + var theme = new ControlTheme(typeof(ListBoxItem)); var target = new ListBox { Template = ListBoxTemplate(), diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index 330cbfd7b9..100e813326 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -998,6 +998,7 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Order_Of_Setting_Items_And_SelectedIndex_During_Initialization_Should_Not_Matter() { + using var app = Start(); var items = new[] { "Foo", "Bar" }; var target = new SelectingItemsControl(); @@ -1015,6 +1016,7 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Order_Of_Setting_Items_And_SelectedItem_During_Initialization_Should_Not_Matter() { + using var app = Start(); var items = new[] { "Foo", "Bar" }; var target = new SelectingItemsControl(); @@ -1847,6 +1849,7 @@ namespace Avalonia.Controls.UnitTests.Primitives public void Preserves_SelectedItem_When_Items_Changed() { // Issue #4048 + using var app = Start(); var target = new SelectingItemsControl { Items = new[] { "foo", "bar", "baz"}, @@ -1867,6 +1870,7 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Setting_SelectedItems_Raises_PropertyChanged() { + using var app = Start(); var target = new TestSelector { Items = new[] { "foo", "bar", "baz" }, @@ -1895,6 +1899,7 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Setting_Selection_Raises_SelectedItems_PropertyChanged() { + using var app = Start(); var target = new TestSelector { Items = new[] { "foo", "bar", "baz" }, @@ -2050,6 +2055,13 @@ namespace Avalonia.Controls.UnitTests.Primitives } } + private static IDisposable Start() + { + return UnitTestApplication.Start(new TestServices( + fontManagerImpl: new MockFontManagerImpl(), + textShaperImpl: new MockTextShaperImpl())); + } + private static void Prepare(SelectingItemsControl target) { var root = new TestRoot diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs index 58d2eedb1f..a7609a6704 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs @@ -170,36 +170,41 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Templated_Children_Should_Be_Styled() { - using (UnitTestApplication.Start(TestServices.MockStyler)) - { - TestTemplatedControl target; + TestTemplatedControl target; - var root = new TestRoot + var root = new TestRoot + { + Styles = { - Child = target = new TestTemplatedControl + new Style(x => x.Is()) { - Template = new FuncControlTemplate((_, __) => + Setters = { - return new StackPanel - { - Children = + new Setter(Control.TagProperty, "foo") + } + } + }, + Child = target = new TestTemplatedControl + { + Template = new FuncControlTemplate((_, __) => + { + return new StackPanel + { + Children = { new TextBlock { } } - }; - }), - } - }; + }; + }), + } + }; - target.ApplyTemplate(); + target.ApplyTemplate(); - var styler = Mock.Get(UnitTestApplication.Current.Services.Styler); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - styler.Verify(x => x.ApplyStyles(It.IsAny()), Times.Once()); - } + foreach (Control child in target.GetTemplateChildren()) + Assert.Equal("foo", child.Tag); } [Fact] @@ -351,166 +356,154 @@ namespace Avalonia.Controls.UnitTests.Primitives [Fact] public void Removing_From_LogicalTree_Should_Not_Remove_Child() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + Border templateChild = new Border(); + TestTemplatedControl target; + var root = new TestRoot { - Border templateChild = new Border(); - TestTemplatedControl target; - var root = new TestRoot + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter( - TemplatedControl.TemplateProperty, - new FuncControlTemplate((_, __) => new Decorator - { - Child = new Border(), - })) - } + new Setter( + TemplatedControl.TemplateProperty, + new FuncControlTemplate((_, __) => new Decorator + { + Child = new Border(), + })) } - }, - Child = target = new TestTemplatedControl() - }; + } + }, + Child = target = new TestTemplatedControl() + }; - Assert.NotNull(target.Template); - target.ApplyTemplate(); + Assert.NotNull(target.Template); + target.ApplyTemplate(); - root.Child = null; + root.Child = null; - Assert.Null(target.Template); - Assert.IsType(target.GetVisualChildren().Single()); - } + Assert.Null(target.Template); + Assert.IsType(target.GetVisualChildren().Single()); } [Fact] public void Re_adding_To_Same_LogicalTree_Should_Not_Recreate_Template() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + TestTemplatedControl target; + var root = new TestRoot { - TestTemplatedControl target; - var root = new TestRoot + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter( - TemplatedControl.TemplateProperty, - new FuncControlTemplate((_, __) => new Decorator - { - Child = new Border(), - })) - } + new Setter( + TemplatedControl.TemplateProperty, + new FuncControlTemplate((_, __) => new Decorator + { + Child = new Border(), + })) } - }, - Child = target = new TestTemplatedControl() - }; + } + }, + Child = target = new TestTemplatedControl() + }; - Assert.NotNull(target.Template); - target.ApplyTemplate(); - var expected = (Decorator)target.GetVisualChildren().Single(); + Assert.NotNull(target.Template); + target.ApplyTemplate(); + var expected = (Decorator)target.GetVisualChildren().Single(); - root.Child = null; - root.Child = target; - target.ApplyTemplate(); + root.Child = null; + root.Child = target; + target.ApplyTemplate(); - Assert.Same(expected, target.GetVisualChildren().Single()); - } + Assert.Same(expected, target.GetVisualChildren().Single()); } [Fact] public void Re_adding_To_Different_LogicalTree_Should_Recreate_Template() { - using (UnitTestApplication.Start(TestServices.RealStyler)) - { - TestTemplatedControl target; + TestTemplatedControl target; - var root = new TestRoot + var root = new TestRoot + { + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter( - TemplatedControl.TemplateProperty, - new FuncControlTemplate((_, __) => new Decorator - { - Child = new Border(), - })) - } + new Setter( + TemplatedControl.TemplateProperty, + new FuncControlTemplate((_, __) => new Decorator + { + Child = new Border(), + })) } - }, - Child = target = new TestTemplatedControl() - }; + } + }, + Child = target = new TestTemplatedControl() + }; - var root2 = new TestRoot + var root2 = new TestRoot + { + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter( - TemplatedControl.TemplateProperty, - new FuncControlTemplate((_, __) => new Decorator - { - Child = new Border(), - })) - } + new Setter( + TemplatedControl.TemplateProperty, + new FuncControlTemplate((_, __) => new Decorator + { + Child = new Border(), + })) } - }, - }; + } + }, + }; - Assert.NotNull(target.Template); - target.ApplyTemplate(); + Assert.NotNull(target.Template); + target.ApplyTemplate(); - var expected = (Decorator)target.GetVisualChildren().Single(); + var expected = (Decorator)target.GetVisualChildren().Single(); - root.Child = null; - root2.Child = target; - target.ApplyTemplate(); + root.Child = null; + root2.Child = target; + target.ApplyTemplate(); - var child = target.GetVisualChildren().Single(); - Assert.NotNull(target.Template); - Assert.NotNull(child); - Assert.NotSame(expected, child); - } + var child = target.GetVisualChildren().Single(); + Assert.NotNull(target.Template); + Assert.NotNull(child); + Assert.NotSame(expected, child); } [Fact] public void Moving_To_New_LogicalTree_Should_Detach_Attach_Template_Child() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + TestTemplatedControl target; + var root = new TestRoot { - TestTemplatedControl target; - var root = new TestRoot + Child = target = new TestTemplatedControl { - Child = target = new TestTemplatedControl - { - Template = new FuncControlTemplate((_, __) => new Decorator()), - } - }; + Template = new FuncControlTemplate((_, __) => new Decorator()), + } + }; - Assert.NotNull(target.Template); - target.ApplyTemplate(); + Assert.NotNull(target.Template); + target.ApplyTemplate(); - var templateChild = (ILogical)target.GetVisualChildren().Single(); - Assert.True(templateChild.IsAttachedToLogicalTree); + var templateChild = (ILogical)target.GetVisualChildren().Single(); + Assert.True(templateChild.IsAttachedToLogicalTree); - root.Child = null; - Assert.False(templateChild.IsAttachedToLogicalTree); + root.Child = null; + Assert.False(templateChild.IsAttachedToLogicalTree); - var newRoot = new TestRoot { Child = target }; - Assert.True(templateChild.IsAttachedToLogicalTree); - } + var newRoot = new TestRoot { Child = target }; + Assert.True(templateChild.IsAttachedToLogicalTree); } [Fact] diff --git a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs index c54d7efe61..d8a897d600 100644 --- a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs @@ -227,28 +227,24 @@ namespace Avalonia.Controls.UnitTests }; var template = new FuncControlTemplate((x, __) => new Decorator()); - - using (UnitTestApplication.Start(TestServices.RealStyler)) + var root = new TestRoot { - var root = new TestRoot + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter(TemplatedControl.TemplateProperty, template) - } + new Setter(TemplatedControl.TemplateProperty, template) } - }, - Child = new TabControl - { - Template = TabControlTemplate(), - Items = collection, } - }; - } + }, + Child = new TabControl + { + Template = TabControlTemplate(), + Items = collection, + } + }; Assert.Same(collection[0].Template, template); Assert.Same(collection[1].Template, template); diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index 9cf21423a3..9ae6fd98b5 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -77,7 +77,7 @@ namespace Avalonia.Controls.UnitTests public void Items_Should_Be_Created_Using_ItemConatinerTheme_If_Present() { TreeView target; - var theme = new ControlTheme(); + var theme = new ControlTheme(typeof(TreeViewItem)); var root = new TestRoot { diff --git a/tests/Avalonia.Controls.UnitTests/UserControlTests.cs b/tests/Avalonia.Controls.UnitTests/UserControlTests.cs index 3d1980b0eb..6342d9d21f 100644 --- a/tests/Avalonia.Controls.UnitTests/UserControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/UserControlTests.cs @@ -13,26 +13,23 @@ namespace Avalonia.Controls.UnitTests [Fact] public void Should_Be_Styled_As_UserControl() { - using (UnitTestApplication.Start(TestServices.RealStyler)) + var target = new UserControl(); + var root = new TestRoot { - var target = new UserControl(); - var root = new TestRoot + Styles = { - Styles = + new Style(x => x.OfType()) { - new Style(x => x.OfType()) + Setters = { - Setters = - { - new Setter(TemplatedControl.TemplateProperty, GetTemplate()) - } + new Setter(TemplatedControl.TemplateProperty, GetTemplate()) } - }, - Child = target, - }; + } + }, + Child = target, + }; - Assert.NotNull(target.Template); - } + Assert.NotNull(target.Template); } private FuncControlTemplate GetTemplate() diff --git a/tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs b/tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs index e4d177f7ca..3202924a9d 100644 --- a/tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs @@ -23,11 +23,8 @@ namespace Avalonia.Controls.UnitTests.Utils { using (AvaloniaLocator.EnterScope()) { - var styler = new Mock(); - AvaloniaLocator.CurrentMutable - .Bind().ToConstant(new WindowingPlatformMock()) - .Bind().ToConstant(styler.Object); + .Bind().ToConstant(new WindowingPlatformMock()); var gesture1 = new KeyGesture(Key.A, KeyModifiers.Control); var gesture2 = new KeyGesture(Key.B, KeyModifiers.Control); @@ -67,13 +64,11 @@ namespace Avalonia.Controls.UnitTests.Utils { using (AvaloniaLocator.EnterScope()) { - var styler = new Mock(); var target = new KeyboardDevice(); var commandResult = 0; var expectedParameter = 1; AvaloniaLocator.CurrentMutable - .Bind().ToConstant(new WindowingPlatformMock()) - .Bind().ToConstant(styler.Object); + .Bind().ToConstant(new WindowingPlatformMock()); var gesture = new KeyGesture(Key.A, KeyModifiers.Control); @@ -112,12 +107,10 @@ namespace Avalonia.Controls.UnitTests.Utils { using (AvaloniaLocator.EnterScope()) { - var styler = new Mock(); var target = new KeyboardDevice(); var isExecuted = false; AvaloniaLocator.CurrentMutable - .Bind().ToConstant(new WindowingPlatformMock()) - .Bind().ToConstant(styler.Object); + .Bind().ToConstant(new WindowingPlatformMock()); var gesture = new KeyGesture(Key.A, KeyModifiers.Control); @@ -154,12 +147,10 @@ namespace Avalonia.Controls.UnitTests.Utils { using (AvaloniaLocator.EnterScope()) { - var styler = new Mock(); var target = new KeyboardDevice(); var clickExecutedCount = 0; AvaloniaLocator.CurrentMutable - .Bind().ToConstant(new WindowingPlatformMock()) - .Bind().ToConstant(styler.Object); + .Bind().ToConstant(new WindowingPlatformMock()); var gesture = new KeyGesture(Key.A, KeyModifiers.Control); @@ -208,13 +199,11 @@ namespace Avalonia.Controls.UnitTests.Utils { using (AvaloniaLocator.EnterScope()) { - var styler = new Mock(); var target = new KeyboardDevice(); var clickExecutedCount = 0; var commandExecutedCount = 0; AvaloniaLocator.CurrentMutable - .Bind().ToConstant(new WindowingPlatformMock()) - .Bind().ToConstant(styler.Object); + .Bind().ToConstant(new WindowingPlatformMock()); var gesture = new KeyGesture(Key.A, KeyModifiers.Control); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs index 2d7dcf4b45..88d2cc2912 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Globalization; using System.Linq; using System.Reactive.Subjects; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Presenters; @@ -26,6 +27,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions { public class CompiledBindingExtensionTests { + static CompiledBindingExtensionTests() + { + RuntimeHelpers.RunClassConstructor(typeof(RelativeSource).TypeHandle); + } + [Fact] public void ResolvesClrPropertyBasedOnDataContextType() { diff --git a/tests/Avalonia.UnitTests/TestServices.cs b/tests/Avalonia.UnitTests/TestServices.cs index 49da2794c1..c421adaf21 100644 --- a/tests/Avalonia.UnitTests/TestServices.cs +++ b/tests/Avalonia.UnitTests/TestServices.cs @@ -23,7 +23,6 @@ namespace Avalonia.UnitTests platform: new AppBuilder().RuntimePlatform, renderInterface: new MockPlatformRenderInterface(), standardCursorFactory: Mock.Of(), - styler: new Styler(), theme: () => CreateSimpleTheme(), threadingInterface: Mock.Of(x => x.CurrentThreadIsLoopThread == true), fontManagerImpl: new MockFontManagerImpl(), @@ -39,9 +38,6 @@ namespace Avalonia.UnitTests public static readonly TestServices MockPlatformWrapper = new TestServices( platform: Mock.Of()); - public static readonly TestServices MockStyler = new TestServices( - styler: Mock.Of()); - public static readonly TestServices MockThreadingInterface = new TestServices( threadingInterface: Mock.Of(x => x.CurrentThreadIsLoopThread == true)); @@ -58,9 +54,6 @@ namespace Avalonia.UnitTests fontManagerImpl: new MockFontManagerImpl(), textShaperImpl: new MockTextShaperImpl()); - public static readonly TestServices RealStyler = new TestServices( - styler: new Styler()); - public static readonly TestServices TextServices = new TestServices( assetLoader: new AssetLoader(), renderInterface: new MockPlatformRenderInterface(), @@ -80,7 +73,6 @@ namespace Avalonia.UnitTests IRenderTimer renderLoop = null, IScheduler scheduler = null, ICursorFactory standardCursorFactory = null, - IStyler styler = null, Func theme = null, IPlatformThreadingInterface threadingInterface = null, IFontManagerImpl fontManagerImpl = null, @@ -101,7 +93,6 @@ namespace Avalonia.UnitTests TextShaperImpl = textShaperImpl; Scheduler = scheduler; StandardCursorFactory = standardCursorFactory; - Styler = styler; Theme = theme; ThreadingInterface = threadingInterface; WindowImpl = windowImpl; @@ -121,7 +112,6 @@ namespace Avalonia.UnitTests public ITextShaperImpl TextShaperImpl { get; } public IScheduler Scheduler { get; } public ICursorFactory StandardCursorFactory { get; } - public IStyler Styler { get; } public Func Theme { get; } public IPlatformThreadingInterface ThreadingInterface { get; } public IWindowImpl WindowImpl { get; } @@ -140,8 +130,7 @@ namespace Avalonia.UnitTests IRenderTimer renderLoop = null, IScheduler scheduler = null, ICursorFactory standardCursorFactory = null, - IStyler styler = null, - Func theme = null, + Func theme = null, IPlatformThreadingInterface threadingInterface = null, IFontManagerImpl fontManagerImpl = null, ITextShaperImpl textShaperImpl = null, @@ -162,7 +151,6 @@ namespace Avalonia.UnitTests textShaperImpl: textShaperImpl ?? TextShaperImpl, scheduler: scheduler ?? Scheduler, standardCursorFactory: standardCursorFactory ?? StandardCursorFactory, - styler: styler ?? Styler, theme: theme ?? Theme, threadingInterface: threadingInterface ?? ThreadingInterface, windowingPlatform: windowingPlatform ?? WindowingPlatform, diff --git a/tests/Avalonia.UnitTests/UnitTestApplication.cs b/tests/Avalonia.UnitTests/UnitTestApplication.cs index 260771c9ab..03e19359c3 100644 --- a/tests/Avalonia.UnitTests/UnitTestApplication.cs +++ b/tests/Avalonia.UnitTests/UnitTestApplication.cs @@ -68,14 +68,13 @@ namespace Avalonia.UnitTests .Bind().ToConstant(Services.ThreadingInterface) .Bind().ToConstant(Services.Scheduler) .Bind().ToConstant(Services.StandardCursorFactory) - .Bind().ToConstant(Services.Styler) .Bind().ToConstant(Services.WindowingPlatform) .Bind().ToSingleton(); var theme = Services.Theme?.Invoke(); - if (theme is Styles styles) + if (theme is Style styles) { - Styles.AddRange(styles); + Styles.AddRange(styles.Children); } else if (theme is not null) {