Explorar o código

Merge pull request #1711 from AvaloniaUI/fixes/1709-changing-listbox-template

Clear ItemContainerGenerator when ItemsPresenter changed.
Steven Kirk %!s(int64=7) %!d(string=hai) anos
pai
achega
3c37681549

+ 1 - 0
src/Avalonia.Controls/ItemsControl.cs

@@ -155,6 +155,7 @@ namespace Avalonia.Controls
         void IItemsPresenterHost.RegisterItemsPresenter(IItemsPresenter presenter)
         {
             Presenter = presenter;
+            ItemContainerGenerator.Clear();
         }
 
         /// <summary>

+ 7 - 4
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@@ -408,12 +408,15 @@ namespace Avalonia.Controls.Primitives
 
             var panel = (InputElement)Presenter.Panel;
 
-            foreach (var container in e.Containers)
+            if (panel != null)
             {
-                if (KeyboardNavigation.GetTabOnceActiveElement(panel) == container.ContainerControl)
+                foreach (var container in e.Containers)
                 {
-                    KeyboardNavigation.SetTabOnceActiveElement(panel, null);
-                    break;
+                    if (KeyboardNavigation.GetTabOnceActiveElement(panel) == container.ContainerControl)
+                    {
+                        KeyboardNavigation.SetTabOnceActiveElement(panel, null);
+                        break;
+                    }
                 }
             }
         }

+ 1 - 0
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@@ -247,6 +247,7 @@ namespace Avalonia.Controls.Primitives
                     foreach (var child in this.GetTemplateChildren())
                     {
                         child.SetValue(TemplatedParentProperty, null);
+                        ((ISetLogicalParent)child).SetParent(null);
                     }
 
                     VisualChildren.Clear();

+ 20 - 0
tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs

@@ -315,6 +315,26 @@ namespace Avalonia.Controls.UnitTests
             Assert.Same(before, after);
         }
 
+        [Fact]
+        public void Should_Clear_Containers_When_ItemsPresenter_Changes()
+        {
+            var target = new ItemsControl
+            {
+                Items = new[] { "foo", "bar" },
+                Template = GetTemplate(),
+            };
+
+            target.ApplyTemplate();
+            target.Presenter.ApplyTemplate();
+
+            Assert.Equal(2, target.ItemContainerGenerator.Containers.Count());
+
+            target.Template = GetTemplate();
+            target.ApplyTemplate();
+
+            Assert.Empty(target.ItemContainerGenerator.Containers);
+        }
+
         [Fact]
         public void Empty_Class_Should_Initially_Be_Applied()
         {

+ 18 - 0
tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs

@@ -160,6 +160,24 @@ namespace Avalonia.Controls.UnitTests.Primitives
             Assert.Equal(target, child.GetLogicalParent());
         }
 
+        [Fact]
+        public void Changing_Template_Should_Clear_Old_Templated_Childs_Parent()
+        {
+            var target = new TemplatedControl
+            {
+                Template = new FuncControlTemplate(_ => new Decorator())
+            };
+
+            target.ApplyTemplate();
+
+            var child = (Decorator)target.GetVisualChildren().Single();
+
+            target.Template = new FuncControlTemplate(_ => new Canvas());
+            target.ApplyTemplate();
+
+            Assert.Null(child.Parent);
+        }
+
         [Fact]
         public void Nested_Templated_Control_Should_Not_Have_Template_Applied()
         {