| 
					
				 | 
			
			
				@@ -3,6 +3,7 @@ using System.Collections; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Collections.Generic; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Collections.Specialized; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.ComponentModel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using System.Diagnostics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Linq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.Animation; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.Collections; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11,6 +12,7 @@ using Avalonia.Data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.Diagnostics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.Logging; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.LogicalTree; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using Avalonia.PropertyStore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Avalonia.Styling; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace Avalonia 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -69,10 +71,10 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private IAvaloniaList<ILogical>? _logicalChildren; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private IResourceDictionary? _resources; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Styles? _styles; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private bool _styled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private bool _stylesApplied; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private bool _themeApplied; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private ITemplatedControl? _templatedParent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool _dataContextUpdating; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private bool _hasPromotedTheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private ControlTheme? _implicitTheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -141,7 +143,7 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             set 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (_styled) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (_stylesApplied) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     throw new InvalidOperationException("Cannot set Name : styled element already styled."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -353,38 +355,33 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </returns> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public bool ApplyStyling() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (_initCount == 0 && !_styled) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (_initCount == 0 && (!_stylesApplied || !_themeApplied)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var hasPromotedTheme = _hasPromotedTheme; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 GetValueStore().BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ApplyControlTheme(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ApplyStyles(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!_themeApplied) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ApplyControlTheme(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        _themeApplied = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!_stylesApplied) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ApplyStyles(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        _stylesApplied = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _styled = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     GetValueStore().EndStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hasPromotedTheme) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _hasPromotedTheme = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ClearValue(ThemeProperty); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return _styled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return _stylesApplied; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Detaches all styles from the element and queues a restyle. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        protected virtual void InvalidateStyles() => DetachStyles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected void InitializeIfNeeded() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (_initCount == 0 && !IsInitialized) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -506,17 +503,16 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        void IStyleable.DetachStyles() => DetachStyles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         void IStyleHost.StylesAdded(IReadOnlyList<IStyle> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            InvalidateStylesOnThisAndDescendents(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (HasSettersOrAnimations(styles)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                InvalidateStyles(recurse: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         void IStyleHost.StylesRemoved(IReadOnlyList<IStyle> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var allStyles = RecurseStyles(styles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            DetachStylesFromThisAndDescendents(allStyles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (FlattenStyles(styles) is { } allStyles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DetachStyles(allStyles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         protected virtual void LogicalChildrenCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -615,31 +611,25 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (change.Property == ThemeProperty) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var (oldValue, newValue) = change.GetOldAndNewValue<ControlTheme?>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // Changing the theme detaches all styles, meaning that if the theme property was 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // set via a style, it will get cleared! To work around this, if the value was 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // applied at less than local value priority then promote the value to local value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // priority until styling is re-applied. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (change.Priority > BindingPriority.LocalValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    Theme = newValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _hasPromotedTheme = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else if (_hasPromotedTheme && change.Priority == BindingPriority.LocalValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _hasPromotedTheme = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                InvalidateStyles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (oldValue is not null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    DetachControlThemeFromTemplateChildren(oldValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                OnControlThemeChanged(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _themeApplied = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        internal virtual void DetachControlThemeFromTemplateChildren(ControlTheme theme) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private protected virtual void OnControlThemeChanged() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var values = GetValueStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            values.BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { values.RemoveFrames(FrameType.Theme); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            finally { values.EndStyling(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        internal virtual void OnTemplatedParentControlThemeChanged() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var values = GetValueStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            values.BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { values.RemoveFrames(FrameType.TemplatedParentTheme); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            finally { values.EndStyling(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         internal ControlTheme? GetEffectiveTheme() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -667,6 +657,23 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        internal virtual void InvalidateStyles(bool recurse) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var values = GetValueStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            values.BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { values.RemoveFrames(FrameType.Style); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            finally { values.EndStyling(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _stylesApplied = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (recurse && GetInheritanceChildren() is { } children) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var childCount = children.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (var i = 0; i < childCount; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    (children[i] as StyledElement)?.InvalidateStyles(recurse); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private static void DataContextNotifying(IAvaloniaObject o, bool updateStarted) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (o is StyledElement element) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -736,26 +743,28 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var theme = GetEffectiveTheme(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (theme is not null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ApplyControlTheme(theme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ApplyControlTheme(theme, FrameType.Theme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (TemplatedParent is StyledElement styleableParent && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 styleableParent.GetEffectiveTheme() is { } parentTheme) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ApplyControlTheme(parentTheme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ApplyControlTheme(parentTheme, FrameType.TemplatedParentTheme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void ApplyControlTheme(ControlTheme theme) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private void ApplyControlTheme(ControlTheme theme, FrameType type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Debug.Assert(type is FrameType.Theme or FrameType.TemplatedParentTheme); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (theme.BasedOn is ControlTheme basedOn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ApplyControlTheme(basedOn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ApplyControlTheme(basedOn, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            theme.TryAttach(this, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            theme.TryAttach(this, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (theme.HasChildren) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 foreach (var child in theme.Children) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ApplyStyle(child, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ApplyStyle(child, null, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -768,17 +777,17 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (host.IsStylesInitialized) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 foreach (var style in host.Styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ApplyStyle(style, host); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ApplyStyle(style, host, FrameType.Style); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void ApplyStyle(IStyle style, IStyleHost? host) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private void ApplyStyle(IStyle style, IStyleHost? host, FrameType type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (style is Style s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                s.TryAttach(this, host); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                s.TryAttach(this, host, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             foreach (var child in style.Children) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ApplyStyle(child, host); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ApplyStyle(child, host, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private void OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -824,7 +833,7 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 _logicalRoot = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 _implicitTheme = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                DetachStyles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                InvalidateStyles(recurse: false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 OnDetachedFromLogicalTree(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 DetachedFromLogicalTree?.Invoke(this, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -886,70 +895,81 @@ namespace Avalonia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void DetachStyles(IReadOnlyList<StyleBase>? styles = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private void DetachStyles(IReadOnlyList<Style> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var valueStore = GetValueStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var values = GetValueStore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            values.BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { values.RemoveFrames(styles); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            finally { values.EndStyling(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            valueStore.BeginStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (var i = valueStore.Frames.Count - 1; i >= 0; --i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (_logicalChildren is not null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (valueStore.Frames[i] is StyleInstance si && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    (styles is null || styles.Contains(si.Source))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var childCount = _logicalChildren.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (var i = 0; i < childCount; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    valueStore.RemoveFrame(si); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    (_logicalChildren[i] as StyledElement)?.DetachStyles(styles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            valueStore.EndStyling(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _styled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void InvalidateStylesOnThisAndDescendents() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private void NotifyResourcesChanged( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ResourcesChangedEventArgs? e = null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bool propagate = true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            InvalidateStyles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (_logicalChildren is object) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ResourcesChanged is object) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var childCount = _logicalChildren.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                e ??= ResourcesChangedEventArgs.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ResourcesChanged(this, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                for (var i = 0; i < childCount; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    (_logicalChildren[i] as StyledElement)?.InvalidateStylesOnThisAndDescendents(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (propagate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                e ??= ResourcesChangedEventArgs.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                NotifyChildResourcesChanged(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void DetachStylesFromThisAndDescendents(IReadOnlyList<StyleBase> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static IReadOnlyList<Style>? FlattenStyles(IReadOnlyList<IStyle> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            DetachStyles(styles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<Style>? result = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (_logicalChildren is object) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            static void FlattenStyle(IStyle style, ref List<Style>? result) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var childCount = _logicalChildren.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (style is Style s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    (result ??= new()).Add(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FlattenStyles(style.Children, ref result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                for (var i = 0; i < childCount; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    (_logicalChildren[i] as StyledElement)?.DetachStylesFromThisAndDescendents(styles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            static void FlattenStyles(IReadOnlyList<IStyle> styles, ref List<Style>? result) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var count = styles.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (var i = 0; i < count; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    FlattenStyle(styles[i], ref result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FlattenStyles(styles, ref result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void NotifyResourcesChanged( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ResourcesChangedEventArgs? e = null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bool propagate = true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static bool HasSettersOrAnimations(IReadOnlyList<IStyle> styles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (ResourcesChanged is object) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            static bool StyleHasSettersOrAnimations(IStyle style) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                e ??= ResourcesChangedEventArgs.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ResourcesChanged(this, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (style is StyleBase s && s.HasSettersOrAnimations) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return HasSettersOrAnimations(style.Children); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (propagate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var count = styles.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (var i = 0; i < count; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                e ??= ResourcesChangedEventArgs.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                NotifyChildResourcesChanged(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (StyleHasSettersOrAnimations(styles[i])) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private static IReadOnlyList<StyleBase> RecurseStyles(IReadOnlyList<IStyle> styles) 
			 |