瀏覽代碼

Correctly select materialized containers.

And add another test.
Steven Kirk 6 年之前
父節點
當前提交
fc9a8db010

+ 23 - 11
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@@ -342,24 +342,36 @@ namespace Avalonia.Controls.Primitives
         {
             base.OnContainersMaterialized(e);
 
-            var selectedIndex = SelectedIndex;
-            var selectedContainer = e.Containers
-                .FirstOrDefault(x => (x.ContainerControl as ISelectable)?.IsSelected == true);
+            var resetSelectedItems = false;
 
-            if (selectedContainer != null)
+            foreach (var container in e.Containers)
             {
-                SelectedIndex = selectedContainer.Index;
-            }
-            else if (selectedIndex >= e.StartingIndex &&
-                     selectedIndex < e.StartingIndex + e.Containers.Count)
-            {
-                var container = e.Containers[selectedIndex - e.StartingIndex];
+                if ((container.ContainerControl as ISelectable)?.IsSelected == true)
+                {
+                    if (SelectedIndex == -1)
+                    {
+                        SelectedIndex = container.Index;
+                    }
+                    else
+                    {
+                        if (_selection.Add(container.Index))
+                        {
+                            resetSelectedItems = true;
+                        }
+                    }
 
-                if (container.ContainerControl != null)
+                    MarkContainerSelected(container.ContainerControl, true);
+                }
+                else if (_selection.Contains(container.Index))
                 {
                     MarkContainerSelected(container.ContainerControl, true);
                 }
             }
+
+            if (resetSelectedItems)
+            {
+                ResetSelectedItems();
+            }
         }
 
         /// <inheritdoc/>

+ 31 - 0
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

@@ -1068,6 +1068,31 @@ namespace Avalonia.Controls.UnitTests.Primitives
             Assert.Equal(1, target.SelectedItems.Count);
         }
 
+        [Fact]
+        public void Adding_Selected_ItemContainers_Should_Update_Selection()
+        {
+            var items = new AvaloniaList<ItemContainer>(new[]
+            {
+                new ItemContainer(),
+                new ItemContainer(),
+            });
+
+            var target = new TestSelector
+            {
+                Items = items,
+                Template = Template(),
+            };
+
+            target.ApplyTemplate();
+            target.Presenter.ApplyTemplate();
+            items.Add(new ItemContainer { IsSelected = true });
+            items.Add(new ItemContainer { IsSelected = true });
+
+            Assert.Equal(2, target.SelectedIndex);
+            Assert.Equal(items[2], target.SelectedItem);
+            Assert.Equal(new[] { items[2], items[3] }, target.SelectedItems);
+        }
+
         private IEnumerable<int> SelectedContainers(SelectingItemsControl target)
         {
             return target.Presenter.Panel.Children
@@ -1120,5 +1145,11 @@ namespace Avalonia.Controls.UnitTests.Primitives
             public List<string> Items { get; } 
             public List<string> SelectedItems { get; }
         }
+
+        private class ItemContainer : Control, ISelectable
+        {
+            public string Value { get; set; }
+            public bool IsSelected { get; set; }
+        }
     }
 }