소스 검색

Only subscribe to Path.Data when Path is attached to the visual tree.

Dariusz Komosinski 5 년 전
부모
커밋
93320e4759
2개의 변경된 파일35개의 추가작업 그리고 3개의 파일을 삭제
  1. 31 3
      src/Avalonia.Controls/Shapes/Path.cs
  2. 4 0
      tests/Avalonia.Controls.UnitTests/Shapes/PathTests.cs

+ 31 - 3
src/Avalonia.Controls/Shapes/Path.cs

@@ -1,5 +1,4 @@
 using System;
-using Avalonia.Data;
 using Avalonia.Media;
 
 namespace Avalonia.Controls.Shapes
@@ -9,6 +8,8 @@ namespace Avalonia.Controls.Shapes
         public static readonly StyledProperty<Geometry> DataProperty =
             AvaloniaProperty.Register<Path, Geometry>(nameof(Data));
 
+        private EventHandler _geometryChangedHandler;
+
         static Path()
         {
             AffectsGeometry<Path>(DataProperty);
@@ -21,21 +22,48 @@ namespace Avalonia.Controls.Shapes
             set { SetValue(DataProperty, value); }
         }
 
+        private EventHandler GeometryChangedHandler => _geometryChangedHandler ??= GeometryChanged;
+
         protected override Geometry CreateDefiningGeometry() => Data;
 
+        protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+        {
+            base.OnAttachedToVisualTree(e);
+
+            if (Data is object)
+            {
+                Data.Changed += GeometryChangedHandler;
+            }
+        }
+
+        protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+        {
+            base.OnDetachedFromVisualTree(e);
+
+            if (Data is object)
+            {
+                Data.Changed -= GeometryChangedHandler;
+            }
+        }
+
         private void DataChanged(AvaloniaPropertyChangedEventArgs e)
         {
+            if (VisualRoot is null)
+            {
+                return;
+            }
+
             var oldGeometry = (Geometry)e.OldValue;
             var newGeometry = (Geometry)e.NewValue;
 
             if (oldGeometry is object)
             {
-                oldGeometry.Changed -= GeometryChanged;
+                oldGeometry.Changed -= GeometryChangedHandler;
             }
 
             if (newGeometry is object)
             {
-                newGeometry.Changed += GeometryChanged;
+                newGeometry.Changed += GeometryChangedHandler;
             }
         }
 

+ 4 - 0
tests/Avalonia.Controls.UnitTests/Shapes/PathTests.cs

@@ -23,12 +23,16 @@ namespace Avalonia.Controls.UnitTests.Shapes
             var geometry = new EllipseGeometry { Rect = new Rect(0, 0, 10, 10) };
             var target = new Path { Data = geometry };
 
+            var root = new TestRoot(target);
+
             target.Measure(Size.Infinity);
             Assert.True(target.IsMeasureValid);
 
             geometry.Rect = new Rect(0, 0, 20, 20);
 
             Assert.False(target.IsMeasureValid);
+
+            root.Child = null;
         }
     }
 }