diff --git a/src/Avalonia.Base/PropertyStore/ValueStore.cs b/src/Avalonia.Base/PropertyStore/ValueStore.cs
index 8790991182..d858e30212 100644
--- a/src/Avalonia.Base/PropertyStore/ValueStore.cs
+++ b/src/Avalonia.Base/PropertyStore/ValueStore.cs
@@ -610,8 +610,7 @@ namespace Avalonia.PropertyStore
private int InsertFrame(ValueFrame frame)
{
- // Uncomment this line when #8549 is fixed.
- //Debug.Assert(!_frames.Contains(frame));
+ Debug.Assert(!_frames.Contains(frame));
var index = BinarySearchFrame(frame.Priority);
_frames.Insert(index, frame);
diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs
index bba9685ed8..c72f398fd9 100644
--- a/src/Avalonia.Base/StyledElement.cs
+++ b/src/Avalonia.Base/StyledElement.cs
@@ -344,29 +344,30 @@ namespace Avalonia
/// Applies styling to the control if the control is initialized and styling is not
/// already applied.
///
+ ///
+ /// The styling system will automatically apply styling when required, so it should not
+ /// usually be necessary to call this method manually.
+ ///
///
/// A value indicating whether styling is now applied to the control.
///
- protected bool ApplyStyling()
+ public bool ApplyStyling()
{
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)
@@ -505,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)
@@ -666,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)
@@ -730,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..90af881adc 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,8 +182,6 @@ namespace Avalonia.Controls
_globalStyles.GlobalStylesRemoved += ((IStyleHost)this).StylesRemoved;
}
- styler?.ApplyStyles(this);
-
ClientSize = impl.ClientSize;
FrameSize = impl.FrameSize;
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index 1a7dca737e..559d674c02 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -647,6 +647,7 @@ namespace Avalonia.Controls
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent));
EnsureInitialized();
+ ApplyStyling();
IsVisible = true;
var initialSize = new Size(
@@ -726,6 +727,7 @@ namespace Avalonia.Controls
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent));
EnsureInitialized();
+ ApplyStyling();
IsVisible = true;
var initialSize = new Size(
diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs
index 89483cd566..8f1b2198ad 100644
--- a/src/Avalonia.Controls/WindowBase.cs
+++ b/src/Avalonia.Controls/WindowBase.cs
@@ -149,6 +149,7 @@ namespace Avalonia.Controls
try
{
EnsureInitialized();
+ ApplyStyling();
IsVisible = true;
if (!_hasExecutedInitialLayoutPass)
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/Styling/StyleAttachBenchmark.cs b/tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs
deleted file mode 100644
index 7dad517e51..0000000000
--- a/tests/Avalonia.Benchmarks/Styling/StyleAttachBenchmark.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using Avalonia.Controls;
-using Avalonia.Styling;
-using Avalonia.UnitTests;
-using BenchmarkDotNet.Attributes;
-
-namespace Avalonia.Benchmarks.Styling
-{
- [MemoryDiagnoser]
- public class StyleAttachBenchmark : IDisposable
- {
- private readonly IDisposable _app;
- private readonly TestRoot _root;
- private readonly TextBox _control;
-
- public StyleAttachBenchmark()
- {
- _app = UnitTestApplication.Start(
- TestServices.StyledWindow.With(
- renderInterface: new NullRenderingPlatform(),
- threadingInterface: new NullThreadingPlatform()));
-
- _root = new TestRoot(true, null)
- {
- Renderer = new NullRenderer(),
- };
-
- _control = new TextBox();
- }
-
- [Benchmark]
- [MethodImpl(MethodImplOptions.NoInlining)]
- public void AttachTextBoxStyles()
- {
- var styles = UnitTestApplication.Current.Styles;
-
- styles.TryAttach(_control, UnitTestApplication.Current);
- ((IStyleable)_control).DetachStyles();
- }
-
- public void Dispose()
- {
- _app.Dispose();
- }
- }
-}
diff --git a/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs b/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs
new file mode 100644
index 0000000000..fa8ad00bf8
--- /dev/null
+++ b/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using Avalonia.Controls;
+using Avalonia.Styling;
+using Avalonia.UnitTests;
+using BenchmarkDotNet.Attributes;
+
+namespace Avalonia.Benchmarks.Styling
+{
+ [MemoryDiagnoser]
+ public class Style_Apply_Detach_Complex : IDisposable
+ {
+ private readonly IDisposable _app;
+ private readonly TestRoot _root;
+ private readonly TextBox _control;
+
+ public Style_Apply_Detach_Complex()
+ {
+ _app = UnitTestApplication.Start(
+ TestServices.StyledWindow.With(
+ renderInterface: new NullRenderingPlatform(),
+ threadingInterface: new NullThreadingPlatform()));
+
+ // Simulate an application with a lot of styles by creating a tree of nested panels,
+ // each with a bunch of styles applied.
+ var (rootPanel, leafPanel) = CreateNestedPanels(10);
+
+ // We're benchmarking how long it takes to apply styles to a TextBox in this situation.
+ _control = new TextBox();
+ leafPanel.Children.Add(_control);
+
+ _root = new TestRoot(true, rootPanel)
+ {
+ Renderer = new NullRenderer(),
+ };
+ }
+
+ [Benchmark]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public void Apply_Detach_Styles()
+ {
+ // Styles will have already been attached when attached to the logical tree, so remove
+ // the styles first.
+ if ((string)_control.Tag != "TextBox")
+ throw new Exception("Invalid benchmark state");
+
+ ((IStyleable)_control).DetachStyles();
+
+ if (_control.Tag is not null)
+ throw new Exception("Invalid benchmark state");
+
+ // Then re-apply the styles.
+ _control.ApplyStyling();
+ }
+
+ public void Dispose()
+ {
+ _app.Dispose();
+ }
+
+ private static (Panel, Panel) CreateNestedPanels(int count)
+ {
+ var root = new Panel();
+ var last = root;
+
+ for (var i = 0; i < count; ++i)
+ {
+ var panel = new Panel();
+ panel.Styles.AddRange(CreateStyles());
+ last.Children.Add(panel);
+ last = panel;
+ }
+
+ return (root, last);
+ }
+
+ private static IEnumerable CreateStyles()
+ {
+ var types = new[]
+ {
+ typeof(Border),
+ typeof(Button),
+ typeof(ButtonSpinner),
+ typeof(Carousel),
+ typeof(CheckBox),
+ typeof(ComboBox),
+ typeof(ContentControl),
+ typeof(Expander),
+ typeof(ItemsControl),
+ typeof(Label),
+ typeof(ListBox),
+ typeof(ProgressBar),
+ typeof(RadioButton),
+ typeof(RepeatButton),
+ typeof(ScrollViewer),
+ typeof(Slider),
+ typeof(Spinner),
+ typeof(SplitView),
+ typeof(TextBox),
+ typeof(ToggleSwitch),
+ typeof(TreeView),
+ typeof(Viewbox),
+ typeof(Window),
+ };
+
+ foreach (var type in types)
+ {
+ yield return new Style(x => x.OfType(type))
+ {
+ Setters = { new Setter(Control.TagProperty, type.Name) }
+ };
+
+ yield return new Style(x => x.OfType(type).Class("foo"))
+ {
+ Setters = { new Setter(Control.TagProperty, type.Name + " foo") }
+ };
+
+ yield return new Style(x => x.OfType(type).Class("bar"))
+ {
+ Setters = { new Setter(Control.TagProperty, type.Name + " bar") }
+ };
+ }
+ }
+ }
+}
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/AutoCompleteBoxTests.cs b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
index c8bd289e54..9d71e3bffc 100644
--- a/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
@@ -1056,6 +1056,7 @@ namespace Avalonia.Controls.UnitTests
control.Items = CreateSimpleStringArray();
TextBox textBox = GetTextBox(control);
var window = new Window {Content = control};
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
Dispatcher.UIThread.RunJobs();
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/ContextMenuTests.cs b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs
index b63cbd286e..a798801f20 100644
--- a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs
@@ -29,6 +29,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -61,6 +62,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -130,6 +132,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -158,6 +161,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -186,6 +190,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -207,6 +212,7 @@ namespace Avalonia.Controls.UnitTests
};
var window = new Window { Content = target };
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -390,7 +396,8 @@ namespace Avalonia.Controls.UnitTests
var sp = new StackPanel { Children = { target1, target2 } };
var window = new Window { Content = sp };
-
+
+ window.ApplyStyling();
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
@@ -594,6 +601,7 @@ namespace Avalonia.Controls.UnitTests
windowImpl.Setup(x => x.CreateRenderer(It.IsAny())).Returns(renderer.Object);
var w = new Window(windowImpl.Object) { Content = content };
+ w.ApplyStyling();
w.ApplyTemplate();
w.Presenter.ApplyTemplate();
return w;
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/MenuItemTests.cs b/tests/Avalonia.Controls.UnitTests/MenuItemTests.cs
index d25a790fde..c19a01facb 100644
--- a/tests/Avalonia.Controls.UnitTests/MenuItemTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/MenuItemTests.cs
@@ -193,6 +193,7 @@ namespace Avalonia.Controls.UnitTests
var target = new MenuItem();
var contextMenu = new ContextMenu { Items = new AvaloniaList