Jeremy Koritzinsky 8 years ago
parent
commit
bdaf4a2046

+ 9 - 5
src/Avalonia.Controls/Control.cs

@@ -487,11 +487,6 @@ namespace Avalonia.Controls
         void ILogical.NotifyResourcesChanged(ResourcesChangedEventArgs e)
         {
             ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
-
-            foreach (var child in LogicalChildren)
-            {
-                child.NotifyResourcesChanged(e);
-            }
         }
 
         /// <inheritdoc/>
@@ -536,6 +531,15 @@ namespace Avalonia.Controls
                 }
 
                 _parent = (IControl)parent;
+
+                if (old != null)
+                {
+                    old.ResourcesChanged -= ThisResourcesChanged; 
+                }
+                if (_parent != null)
+                {
+                    _parent.ResourcesChanged += ThisResourcesChanged; 
+                }
                 ((ILogical)this).NotifyResourcesChanged(new ResourcesChangedEventArgs());
 
                 if (_parent is IStyleRoot || _parent?.IsAttachedToLogicalTree == true || this is IStyleRoot)

+ 7 - 1
src/Avalonia.Controls/Primitives/PopupRoot.cs

@@ -8,6 +8,7 @@ using Avalonia.Interactivity;
 using Avalonia.Layout;
 using Avalonia.Media;
 using Avalonia.Platform;
+using Avalonia.Styling;
 using Avalonia.VisualTree;
 using JetBrains.Annotations;
 
@@ -16,7 +17,7 @@ namespace Avalonia.Controls.Primitives
     /// <summary>
     /// The root window of a <see cref="Popup"/>.
     /// </summary>
-    public class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable
+    public class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IResourceNode
     {
         private IDisposable _presenterSubscription;
 
@@ -66,6 +67,11 @@ namespace Avalonia.Controls.Primitives
         /// </summary>
         IVisual IHostedVisualTreeRoot.Host => Parent;
 
+        /// <summary>
+        /// Gets the styling parent of the popup root.
+        /// </summary>
+        IResourceNode IResourceNode.ResourceParent => Parent;
+
         /// <inheritdoc/>
         public void Dispose() => PlatformImpl?.Dispose();
 

+ 16 - 0
tests/Avalonia.Controls.UnitTests/ControlTests_Resources.cs

@@ -204,6 +204,22 @@ namespace Avalonia.Controls.UnitTests
             Assert.True(raised);
         }
 
+        [Fact]
+        public void Setting_Logical_Parent_Subscribes_To_Parents_ResourceChanged_Event()
+        {
+            var parent = new ContentControl();
+            var child = new Border();
+
+            ((ISetLogicalParent)child).SetParent(parent);
+            var raisedOnChild = false;
+
+            child.ResourcesChanged += (_, __) => raisedOnChild = true;
+
+            parent.Resources.Add("foo", "bar");
+
+            Assert.True(raisedOnChild);
+        }
+
         private IControlTemplate ContentControlTemplate()
         {
             return new FuncControlTemplate<ContentControl>(x =>

+ 20 - 0
tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs

@@ -7,6 +7,7 @@ using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Primitives;
 using Avalonia.Controls.Templates;
 using Avalonia.LogicalTree;
+using Avalonia.Styling;
 using Avalonia.UnitTests;
 using Avalonia.VisualTree;
 using Xunit;
@@ -37,6 +38,25 @@ namespace Avalonia.Controls.UnitTests.Primitives
             }
         }
 
+        [Fact]
+        public void PopupRoot_ResourceParent_Is_Popup()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                var target = new TemplatedControlWithPopup
+                {
+                    PopupContent = new Canvas(),
+                };
+
+                var root = new TestRoot { Child = target };
+
+                target.ApplyTemplate();
+                target.Popup.Open();
+
+                Assert.Equal(target.Popup, ((IResourceNode)target.Popup.PopupRoot).ResourceParent);
+            }
+        }
+
         [Fact]
         public void Attaching_PopupRoot_To_Parent_Logical_Tree_Raises_DetachedFromLogicalTree_And_AttachedToLogicalTree()
         {