Procházet zdrojové kódy

Fix spurious selection changes.

In SelectingItemsControl. This was causing TabControls with transitions
to break.
Steven Kirk před 10 roky
rodič
revize
5b307f653d

+ 15 - 4
src/Perspex.Controls/Primitives/SelectingItemsControl.cs

@@ -82,6 +82,7 @@ namespace Perspex.Controls.Primitives
         private object _selectedItem;
         private IList _selectedItems;
         private bool _ignoreContainerSelectionChanged;
+        private bool _syncingSelectedItems;
         private IList _clearSelectedItemsAfterDataContextChanged;
 
         /// <summary>
@@ -150,8 +151,10 @@ namespace Perspex.Controls.Primitives
                     {
                         if (SelectedItems.Count != 1 || SelectedItems[0] != effective)
                         {
+                            _syncingSelectedItems = true;
                             SelectedItems.Clear();
                             SelectedItems.Add(effective);
+                            _syncingSelectedItems = false;
                         }
                     }
                     else if (SelectedItems.Count > 0)
@@ -283,6 +286,7 @@ namespace Perspex.Controls.Primitives
             }
         }
 
+        /// <inheritdoc/>
         protected override void OnDataContextFinishedChanging()
         {
             if (_clearSelectedItemsAfterDataContextChanged == SelectedItems)
@@ -661,7 +665,10 @@ namespace Perspex.Controls.Primitives
                 case NotifyCollectionChangedAction.Remove:
                     if (SelectedItems.Count == 0)
                     {
-                        SelectedIndex = -1;
+                        if (!_syncingSelectedItems)
+                        {
+                            SelectedIndex = -1;
+                        }
                     }
                     else
                     {
@@ -679,7 +686,11 @@ namespace Perspex.Controls.Primitives
                         MarkContainerSelected(item, false);
                     }
 
-                    SelectedIndex = -1;
+                    if (!_syncingSelectedItems)
+                    {
+                        SelectedIndex = -1;
+                    }
+
                     SelectedItemsAdded(SelectedItems);
                     break;
 
@@ -694,7 +705,7 @@ namespace Perspex.Controls.Primitives
                         MarkItemSelected(item, true);
                     }
 
-                    if (SelectedItem != SelectedItems[0])
+                    if (SelectedItem != SelectedItems[0] && !_syncingSelectedItems)
                     {
                         var oldItem = SelectedItem;
                         var oldIndex = SelectedIndex;
@@ -723,7 +734,7 @@ namespace Perspex.Controls.Primitives
                     MarkItemSelected(item, true);
                 }
 
-                if (SelectedItem == null)
+                if (SelectedItem == null && !_syncingSelectedItems)
                 {
                     var index = IndexOf(Items, items[0]);
 

+ 22 - 0
tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

@@ -1,6 +1,7 @@
 // Copyright (c) The Perspex Project. All rights reserved.
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
@@ -355,6 +356,27 @@ namespace Perspex.Controls.UnitTests.Primitives
             Assert.Equal(new[] { "baz", "qux", "qiz" }, target.SelectedItems.Cast<object>().ToList());
         }
 
+        [Fact]
+        public void Suprious_SelectedIndex_Changes_Should_Not_Be_Triggered()
+        {
+            var target = new TestSelector
+            {
+                Items = new[] { "foo", "bar", "baz" },
+                Template = Template(),
+            };
+
+            target.ApplyTemplate();
+
+            var selectedIndexes = new List<int>();
+            target.GetObservable(TestSelector.SelectedIndexProperty).Subscribe(x => selectedIndexes.Add(x));
+
+            target.SelectedItems = new PerspexList<object> { "bar", "baz" };
+            target.SelectedItem = "foo";
+
+            Assert.Equal(0, target.SelectedIndex);
+            Assert.Equal(new[] { -1, 1, 0 }, selectedIndexes);
+        }
+
         /// <summary>
         /// Tests a problem discovered with ListBox with selection.
         /// </summary>