diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 5119096965..3cb997f615 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -155,6 +155,7 @@ namespace Avalonia.Controls void IItemsPresenterHost.RegisterItemsPresenter(IItemsPresenter presenter) { Presenter = presenter; + ItemContainerGenerator.Clear(); } /// diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index 2e668fda95..a7b8981583 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/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; + } } } } diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index 8514104c91..296134ca48 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/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(); diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index 4da803353e..9ef1e9f0d2 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/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() { diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs index cd71717619..166586ace1 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs +++ b/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() {