diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml index 47b4ce7151..f4d81418ac 100644 --- a/samples/ControlCatalog/Pages/ListBoxPage.xaml +++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml @@ -10,7 +10,13 @@ HorizontalAlignment="Center" Spacing="16"> - + diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 6e0ad66699..da9f619932 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -70,7 +70,6 @@ namespace Avalonia.Controls public ItemsControl() { PseudoClasses.Add(":empty"); - SubscribeToItems(_items); } /// @@ -265,6 +264,11 @@ namespace Avalonia.Controls { } + protected override void OnInitialized() + { + SubscribeToItems(_items); + } + /// /// Handles directional navigation within the . /// @@ -330,7 +334,10 @@ namespace Avalonia.Controls Presenter.Items = newValue; } - SubscribeToItems(newValue); + if (IsInitialized) + { + SubscribeToItems(newValue); + } } /// diff --git a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs index a292910fae..c6ca0fb2bf 100644 --- a/tests/Avalonia.Controls.UnitTests/CarouselTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CarouselTests.cs @@ -4,6 +4,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.LogicalTree; +using Avalonia.UnitTests; using Avalonia.VisualTree; using Xunit; @@ -155,6 +156,7 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -247,6 +249,7 @@ namespace Avalonia.Controls.UnitTests IsVirtualized = false }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index 684486cbae..faaa3ed063 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs @@ -131,6 +131,7 @@ namespace Avalonia.Controls.UnitTests var child = new Control(); var items = new AvaloniaList(child); + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; items.RemoveAt(0); @@ -283,6 +284,7 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo" }; var called = false; + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -303,6 +305,7 @@ namespace Avalonia.Controls.UnitTests var items = new AvaloniaList { "Foo", "Bar" }; var called = false; + var root = new TestRoot(target); target.Template = GetTemplate(); target.Items = items; target.ApplyTemplate(); @@ -376,6 +379,7 @@ namespace Avalonia.Controls.UnitTests Items = new[] { 1, 2, 3 }, }; + var root = new TestRoot(target); Assert.DoesNotContain(":empty", target.Classes); } diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index fe9c7b1261..e43e855ae0 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -170,6 +170,8 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected }; + var root = new TestRoot(listBox); + listBox.BeginInit(); listBox.SelectedIndex = 1; @@ -480,6 +482,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new Item { IsSelected = true }); @@ -531,6 +534,7 @@ namespace Avalonia.Controls.UnitTests.Primitives }; target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); target.SelectedIndex = 1; Assert.Equal(items[1], target.SelectedItem); @@ -549,6 +553,45 @@ namespace Avalonia.Controls.UnitTests.Primitives Assert.NotNull(receivedArgs); Assert.Empty(receivedArgs.AddedItems); Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); + Assert.False(items.Single().IsSelected); + } + + [Fact] + public void Removing_Selected_Item_Should_Clear_Selection_With_BeginInit() + { + var items = new AvaloniaList + { + new Item(), + new Item(), + }; + + var target = new SelectingItemsControl(); + target.BeginInit(); + target.Items = items; + target.Template = Template(); + target.EndInit(); + + target.ApplyTemplate(); + target.Presenter.ApplyTemplate(); + target.SelectedIndex = 0; + + Assert.Equal(items[0], target.SelectedItem); + Assert.Equal(0, target.SelectedIndex); + + SelectionChangedEventArgs receivedArgs = null; + + target.SelectionChanged += (_, args) => receivedArgs = args; + + var removed = items[0]; + + items.RemoveAt(0); + + Assert.Null(target.SelectedItem); + Assert.Equal(-1, target.SelectedIndex); + Assert.NotNull(receivedArgs); + Assert.Empty(receivedArgs.AddedItems); + Assert.Equal(new[] { removed }, receivedArgs.RemovedItems); + Assert.False(items.Single().IsSelected); } [Fact] @@ -879,6 +922,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Items = items, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs index dcf25beb50..e9ec8d114f 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs @@ -1014,6 +1014,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1043,6 +1044,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1076,6 +1078,7 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = SelectionMode.Multiple, }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); @@ -1199,6 +1202,7 @@ namespace Avalonia.Controls.UnitTests.Primitives Template = Template(), }; + var root = new TestRoot(target); target.ApplyTemplate(); target.Presenter.ApplyTemplate(); items.Add(new ItemContainer { IsSelected = true });