From 9bab4af920dceacd11955147624dcf1cfc16069a Mon Sep 17 00:00:00 2001 From: Ahamed-Ali <102580874+Ahamed-Ali@users.noreply.github.com> Date: Thu, 20 Mar 2025 15:38:10 +0530 Subject: [PATCH 1/2] Fixed the Searchbar Focus and Unfocus events issue --- .../TestCases.HostApp/Issues/Issue28419.cs | 28 +++++++++++++++++++ .../Tests/Issues/Issue28419.cs | 22 +++++++++++++++ .../SearchBar/SearchBarHandler.Windows.cs | 24 ++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/Controls/tests/TestCases.HostApp/Issues/Issue28419.cs create mode 100644 src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28419.cs diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28419.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue28419.cs new file mode 100644 index 000000000000..c91dcf03961e --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28419.cs @@ -0,0 +1,28 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 28419, "SearchBar focus/unfocus do not fire on Windows", PlatformAffected.UWP)] +public class Issue28419 : ContentPage +{ + public Issue28419() + { + var label = new Label(); + var searchBar = new SearchBar { Placeholder = "SearchBar", AutomationId = "SearchBar" }; + var entry = new Entry { Placeholder = "Entry", AutomationId = "Entry" }; + + searchBar.Focused += (sender, e) => + { + label.Text = "SearchBar Focused"; + }; + + searchBar.Unfocused += (sender, e) => + { + label.Text = "SearchBar Unfocused"; + }; + + Content = new VerticalStackLayout + { + Spacing = 10, + Children = { label, searchBar, entry } + }; + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28419.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28419.cs new file mode 100644 index 000000000000..fa9f3347b429 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28419.cs @@ -0,0 +1,22 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; +public class Issue28419 : _IssuesUITest +{ + public Issue28419(TestDevice device) : base(device) { } + + public override string Issue => "SearchBar focus/unfocus do not fire on Windows"; + + [Test] + [Category(UITestCategories.SearchBar)] + public void SearchBarShouldTriggerFocusedAndUnFocusedEvents() + { + App.WaitForElement("SearchBar"); + App.Tap("SearchBar"); + App.WaitForElement("SearchBar Focused"); + App.Tap("Entry"); + App.WaitForElement("SearchBar Unfocused"); + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs index b31d8c58ae26..603deb1de86a 100644 --- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs +++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs @@ -18,6 +18,12 @@ protected override void ConnectHandler(AutoSuggestBox platformView) platformView.Loaded += OnLoaded; platformView.QuerySubmitted += OnQuerySubmitted; platformView.TextChanged += OnTextChanged; + //In ViewHandler.Windows, FocusManager.GotFocus and LostFocus are handled for other controls. + // However, for AutoSuggestBox, when handling the GotFocus or LostFocus methods, tapping the AutoSuggestBox causes e.NewFocusedElement and e.OldFocusedElement to be a TextBox (which receives the focus). + // As a result, when comparing the PlatformView with the appropriate handler in FocusManagerMapping, the condition is not satisfied, causing the focus and unfocus methods to not work correctly. + // To address this, I have specifically handled the focus and unfocus events for AutoSuggestBox here. + platformView.GotFocus += OnGotFocus; + platformView.LostFocus += OnLostFocus; } protected override void DisconnectHandler(AutoSuggestBox platformView) @@ -25,6 +31,8 @@ protected override void DisconnectHandler(AutoSuggestBox platformView) platformView.Loaded -= OnLoaded; platformView.QuerySubmitted -= OnQuerySubmitted; platformView.TextChanged -= OnTextChanged; + platformView.GotFocus -= OnGotFocus; + platformView.LostFocus -= OnLostFocus; } public static void MapBackground(ISearchBarHandler handler, ISearchBar searchBar) @@ -148,5 +156,21 @@ void OnTextChanged(AutoSuggestBox? sender, AutoSuggestBoxTextChangedEventArgs e) VirtualView.Text = sender.Text; } + + void OnGotFocus(object sender, UI.Xaml.RoutedEventArgs e) + { + if (VirtualView is not null) + { + VirtualView.IsFocused = true; + } + } + + void OnLostFocus(object sender, UI.Xaml.RoutedEventArgs e) + { + if (VirtualView is not null) + { + VirtualView.IsFocused = false; + } + } } } From eb2de2dd3654ff6b8d881f6dbb4f90a51cce4f94 Mon Sep 17 00:00:00 2001 From: Ahamed-Ali <102580874+Ahamed-Ali@users.noreply.github.com> Date: Fri, 21 Mar 2025 10:34:40 +0530 Subject: [PATCH 2/2] Utilized the existing method in ViewHandler.Windows --- .../src/Handlers/SearchBar/SearchBarHandler.Windows.cs | 10 ++-------- src/Core/src/Handlers/View/ViewHandler.Windows.cs | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs index 603deb1de86a..18816303f28a 100644 --- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs +++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Windows.cs @@ -159,18 +159,12 @@ void OnTextChanged(AutoSuggestBox? sender, AutoSuggestBoxTextChangedEventArgs e) void OnGotFocus(object sender, UI.Xaml.RoutedEventArgs e) { - if (VirtualView is not null) - { - VirtualView.IsFocused = true; - } + UpdateIsFocused(true); } void OnLostFocus(object sender, UI.Xaml.RoutedEventArgs e) { - if (VirtualView is not null) - { - VirtualView.IsFocused = false; - } + UpdateIsFocused(false); } } } diff --git a/src/Core/src/Handlers/View/ViewHandler.Windows.cs b/src/Core/src/Handlers/View/ViewHandler.Windows.cs index 159757c930d1..3be6ac248273 100644 --- a/src/Core/src/Handlers/View/ViewHandler.Windows.cs +++ b/src/Core/src/Handlers/View/ViewHandler.Windows.cs @@ -155,7 +155,7 @@ static void FocusManager_LostFocus(object? sender, FocusManagerLostFocusEventArg } } - void UpdateIsFocused(bool isFocused) + private protected void UpdateIsFocused(bool isFocused) { if (VirtualView is not { } virtualView) {