From b84470bf3df62157a2573e05282b3fddb57e800d Mon Sep 17 00:00:00 2001 From: IanRawley <132860927+IanRawley@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:45:29 +1300 Subject: [PATCH] Fix #13474 by partially reverting #12883 (#13663) * Failing unit test for #13474 * Fix for #13474 by reverting changes to ListBoxItem from #12883 * Version 2 of fix, only marks event handled for Mouse input. * Version 3. Re-raise the event, but backup the source before doing so and restore it after. Closest in functionality to original, but preserves "correct" event source in order to allow Tapped events. --------- Co-authored-by: Jumar Macato <16554748+jmacato@users.noreply.github.com> --- src/Avalonia.Controls/ListBoxItem.cs | 4 ++ .../ListBoxTests.cs | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Avalonia.Controls/ListBoxItem.cs b/src/Avalonia.Controls/ListBoxItem.cs index aa95511524..5ee4854554 100644 --- a/src/Avalonia.Controls/ListBoxItem.cs +++ b/src/Avalonia.Controls/ListBoxItem.cs @@ -104,7 +104,11 @@ namespace Avalonia.Controls // As we only update selection from touch/pen on pointer release, we need to raise // the pointer event on the owner to trigger a commit. if (e.Pointer.Type != PointerType.Mouse) + { + var sourceBackup = e.Source; owner.RaiseEvent(e); + e.Source = sourceBackup; + } e.Handled = true; } diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs index 56f20c6e8e..34ab712fe2 100644 --- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs @@ -1289,6 +1289,55 @@ namespace Avalonia.Controls.UnitTests } } + [Fact] + public void ListBoxItem_Should_Not_Block_Tapped_Events() + { + + // #13474 + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + + Pointer _pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Touch, true); + ulong nextStamp = 1; + + var items = Enumerable.Range(0, 10).Select(x => $"Item {x}").ToArray(); + var target = new ListBox + { + Template = ListBoxTemplate(), + ItemsSource = items, + SelectionMode = SelectionMode.Toggle, + ItemTemplate = new FuncDataTemplate((x, _) => new TextBlock { Height = 10 }) + }; + + Prepare(target); + + var lbItems = target.GetLogicalChildren().OfType().ToArray(); + + var item = lbItems[0]; + + int tappedCount = 0; + target.Tapped += (s, e) => + { + tappedCount++; + }; + + _mouse.Click(item); + Assert.Equal(1, tappedCount); + + // Raise PointerPressed and PointerReleased events with the Left Button pressed. TouchTestHelper + // assumes no button pressed, which prevents it from generating Tapped events, or I would use that. + + item.RaiseEvent(new PointerPressedEventArgs(item, _pointer, (Visual)item, default, nextStamp++, + new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed), KeyModifiers.None)); + + + item.RaiseEvent(new PointerReleasedEventArgs(item, _pointer, (Visual)item, default, nextStamp++, + PointerPointProperties.None, KeyModifiers.None, MouseButton.Left)); + + Assert.Equal(2, tappedCount); + } + } + private static void RaiseKeyEvent(Control target, Key key, KeyModifiers inputModifiers = 0) { target.RaiseEvent(new KeyEventArgs