diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index f8440aac47..ccbdc71b1d 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -62,7 +62,7 @@ namespace Avalonia.Controls.Primitives AvaloniaProperty.RegisterDirect( nameof(SelectedItem), o => o.SelectedItem, - (o, v) => o.SelectedItem = v, + (o, v) => o.SelectedItem = v, defaultBindingMode: BindingMode.TwoWay); /// @@ -88,7 +88,7 @@ namespace Avalonia.Controls.Primitives /// public static readonly RoutedEvent IsSelectedChangedEvent = RoutedEvent.Register( - "IsSelectedChanged", + "IsSelectedChanged", RoutingStrategies.Bubble); /// @@ -96,7 +96,7 @@ namespace Avalonia.Controls.Primitives /// public static readonly RoutedEvent SelectionChangedEvent = RoutedEvent.Register( - "SelectionChanged", + "SelectionChanged", RoutingStrategies.Bubble); private static readonly IList Empty = new object[0]; @@ -521,7 +521,7 @@ namespace Avalonia.Controls.Primitives else if (multi && range) { SynchronizeItems( - SelectedItems, + SelectedItems, GetRange(Items, SelectedIndex, index)); } else @@ -583,7 +583,7 @@ namespace Avalonia.Controls.Primitives } /// - /// Updates the selection based on an event that may have originated in a container that + /// Updates the selection based on an event that may have originated in a container that /// belongs to the control. /// /// The control that raised the event. @@ -595,7 +595,7 @@ namespace Avalonia.Controls.Primitives /// false. /// protected bool UpdateSelectionFromEventSource( - IInteractive eventSource, + IInteractive eventSource, bool select = true, bool rangeModifier = false, bool toggleModifier = false) @@ -807,12 +807,10 @@ namespace Avalonia.Controls.Primitives SelectedIndex = -1; } } - else + + foreach (var item in e.OldItems) { - foreach (var item in e.OldItems) - { - MarkItemSelected(item, false); - } + MarkItemSelected(item, false); } removed = e.OldItems; diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs index bc563c25e2..b6f7c9ec96 100644 --- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs @@ -1,13 +1,11 @@ // Copyright (c) The Avalonia 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.ObjectModel; using System.Linq; using Avalonia.Collections; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; -using Avalonia.Data; +using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Styling; using Avalonia.UnitTests; @@ -196,6 +194,44 @@ namespace Avalonia.Controls.UnitTests target.Presenter.Panel.Children.Cast().Select(x => (string)x.Content)); } + [Fact] + public void Toggle_Selection_Should_Update_Containers() + { + var items = Enumerable.Range(0, 10).Select(x => $"Item {x}").ToArray(); + var target = new ListBox + { + Template = ListBoxTemplate(), + Items = items, + SelectionMode = SelectionMode.Toggle, + ItemTemplate = new FuncDataTemplate(x => new TextBlock { Height = 10 }) + }; + + Prepare(target); + + var lbItems = target.GetLogicalChildren().OfType().ToArray(); + + var item = lbItems[0]; + + Assert.Equal(false, item.IsSelected); + + RaisePressedEvent(target, item, MouseButton.Left); + + Assert.Equal(true, item.IsSelected); + + RaisePressedEvent(target, item, MouseButton.Left); + + Assert.Equal(false, item.IsSelected); + } + + private void RaisePressedEvent(ListBox listBox, ListBoxItem item, MouseButton mouseButton) + { + listBox.RaiseEvent(new PointerPressedEventArgs + { + Source = item, + RoutedEvent = InputElement.PointerPressedEvent, + MouseButton = mouseButton + }); + } [Fact] public void ListBox_After_Scroll_IndexOutOfRangeException_Shouldnt_Be_Thrown()