瀏覽代碼

Don't raise LostSelection when changing source.

Steven Kirk 5 年之前
父節點
當前提交
b499321f68

+ 19 - 14
src/Avalonia.Controls/Selection/SelectionModel.cs

@@ -46,26 +46,30 @@ namespace Avalonia.Controls.Selection
 
                     if (base.Source is object)
                     {
+                        using var update = BatchUpdate();
+                        update.Operation.SkipLostSelection = true;
                         Clear();
                     }
 
                     base.Source = value;
 
-                    using var update = BatchUpdate();
-                    update.Operation.IsSourceUpdate = true;
-
-                    if (_hasInitSelectedItem)
-                    {
-                        SelectedItem = _initSelectedItem;
-                        _initSelectedItem = default;
-                        _hasInitSelectedItem = false;
-                    }
-                    else
+                    using (var update = BatchUpdate())
                     {
-                        TrimInvalidSelections(update.Operation);
-                    }
+                        update.Operation.IsSourceUpdate = true;
+
+                        if (_hasInitSelectedItem)
+                        {
+                            SelectedItem = _initSelectedItem;
+                            _initSelectedItem = default;
+                            _hasInitSelectedItem = false;
+                        }
+                        else
+                        {
+                            TrimInvalidSelections(update.Operation);
+                        }
 
-                    RaisePropertyChanged(nameof(Source));
+                        RaisePropertyChanged(nameof(Source));
+                    }
                 }
             }
         }
@@ -582,7 +586,7 @@ namespace Avalonia.Controls.Selection
                 var oldSelectedIndex = _selectedIndex;
                 var indexesChanged = false;
 
-                if (operation.SelectedIndex == -1 && LostSelection is object)
+                if (operation.SelectedIndex == -1 && LostSelection is object && !operation.SkipLostSelection)
                 {
                     operation.UpdateCount++;
                     LostSelection?.Invoke(this, EventArgs.Empty);
@@ -701,6 +705,7 @@ namespace Avalonia.Controls.Selection
 
             public int UpdateCount { get; set; }
             public bool IsSourceUpdate { get; set; }
+            public bool SkipLostSelection { get; set; }
             public int AnchorIndex { get; set; }
             public int SelectedIndex { get; set; }
             public List<IndexRange>? SelectedRanges { get; set; }

+ 20 - 0
tests/Avalonia.Controls.UnitTests/Selection/SelectionModelTests_Single.cs

@@ -1121,6 +1121,26 @@ namespace Avalonia.Controls.UnitTests.Selection
                 Assert.Equal(0, target.SelectedIndex);
                 Assert.Equal(1, raised);
             }
+
+            [Fact]
+            public void LostSelection_Not_Called_With_Old_Source_When_Changing_Source()
+            {
+                var target = CreateTarget();
+                var data = (AvaloniaList<string>)target.Source!;
+                var raised = 0;
+
+                target.LostSelection += (s, e) =>
+                {
+                    if (target.Source == data)
+                    {
+                        ++raised;
+                    }
+                };
+
+                target.Source = null;
+
+                Assert.Equal(0, raised);
+            }
         }
 
         public class UntypedInterface