Skip to content

Commit 559da79

Browse files
HarishwaranVijayakumarPureWeen
authored andcommitted
[Android, iOS] Dynamically setting SearchHandler Query property does not update text in the search box (#28400)
* Fix for query not updating during runtime * Fix for SearchHandler * Fix for SearchHandler Dynamic Update * Fix for Dynamic SearchHandler QueryProperty * Fix for query not updating in runtime * Fix for searchHandler * Updating the images * Revert "Updating the images" This reverts commit d3959fe. * Modified Test case for search Handler * Modifying the testcase and. the code
1 parent a9108aa commit 559da79

File tree

5 files changed

+148
-0
lines changed

5 files changed

+148
-0
lines changed

src/Controls/src/Core/Compatibility/Handlers/Shell/Android/SearchHandlerAppearanceTracker.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ protected virtual void SearchHandlerPropertyChanged(object sender, System.Compon
8282
{
8383
UpdateAutomationId();
8484
}
85+
else if (e.Is(SearchHandler.QueryProperty))
86+
{
87+
UpdateText();
88+
}
89+
}
90+
91+
void UpdateText()
92+
{
93+
int cursorPosition = _editText.SelectionStart;
94+
bool selectionExists = _editText.HasSelection;
95+
96+
_editText.Text = _searchHandler.Query ?? string.Empty;
97+
98+
UpdateTextTransform();
99+
100+
// If we had a selection, place the cursor at the end of text
101+
// Otherwise try to maintain the cursor at its previous position
102+
int textLength = _editText.Text?.Length ?? 0;
103+
int newPosition = selectionExists ? textLength : Math.Min(cursorPosition, textLength);
104+
105+
// Prevents the cursor from resetting to position zero when text is set programmatically
106+
_editText.SetSelection(newPosition);
85107
}
86108

87109
void EditTextFocusChange(object s, AView.FocusChangeEventArgs args)

src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/SearchHandlerAppearanceTracker.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,19 @@ void SearchHandlerPropertyChanged(object sender, System.ComponentModel.PropertyC
115115
{
116116
UpdateSearchBarVerticalTextAlignment(_uiSearchBar.FindDescendantView<UITextField>());
117117
}
118+
else if (e.Is(SearchHandler.QueryProperty))
119+
{
120+
UpdateText(_uiSearchBar.FindDescendantView<UITextField>());
121+
}
122+
}
123+
124+
void UpdateText(UITextField uiTextField)
125+
{
126+
if (uiTextField is null)
127+
return;
128+
129+
uiTextField.Text = _searchHandler.Query;
130+
UpdateTextTransform(uiTextField);
118131
}
119132

120133
void GetDefaultSearchBarColors(UISearchBar searchBar)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
namespace Maui.Controls.Sample.Issues;
2+
3+
[Issue(IssueTracker.Github, 14497, "Dynamically setting SearchHandler Query property does not update text in the search box", PlatformAffected.Android | PlatformAffected.iOS)]
4+
public class Issue14497 : Shell
5+
{
6+
public Issue14497()
7+
{
8+
ShellContent shellContent = new ShellContent
9+
{
10+
Title = "Home",
11+
ContentTemplate = new DataTemplate(typeof(Issue14497Page)),
12+
Route = "MainPage"
13+
};
14+
15+
Items.Add(shellContent);
16+
}
17+
}
18+
19+
public class Issue14497Page : ContentPage
20+
{
21+
Issue14497CustomSearchHandler _searchHandler;
22+
public Issue14497Page()
23+
{
24+
_searchHandler = new Issue14497CustomSearchHandler();
25+
26+
Button button = new Button
27+
{
28+
Text = "Change Search Text",
29+
AutomationId = "ChangeSearchText"
30+
};
31+
32+
button.Clicked += (s,e) => _searchHandler.SetQuery("Hello World");
33+
34+
VerticalStackLayout stackLayout = new VerticalStackLayout
35+
{
36+
Children = { button }
37+
};
38+
39+
Content = stackLayout;
40+
Shell.SetSearchHandler(this, _searchHandler);
41+
}
42+
}
43+
44+
public class Issue14497CustomSearchHandler : SearchHandler
45+
{
46+
public Issue14497CustomSearchHandler()
47+
{
48+
Placeholder = "Search...";
49+
ShowsResults = false;
50+
}
51+
52+
public void SetQuery(string searchText)
53+
{
54+
Query = searchText;
55+
}
56+
57+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues;
6+
7+
public class Issue14497 : _IssuesUITest
8+
{
9+
public Issue14497(TestDevice device) : base(device) { }
10+
11+
public override string Issue => "Dynamically setting SearchHandler Query property does not update text in the search box";
12+
const string ChangeSearchText = "ChangeSearchText";
13+
14+
[Test]
15+
[Category(UITestCategories.Shell)]
16+
public void DynamicallyQueryNotUpdating()
17+
{
18+
App.WaitForElement(ChangeSearchText);
19+
App.Tap(ChangeSearchText);
20+
var searchHandlerString = App.GetShellSearchHandler().GetText();
21+
Assert.That(searchHandlerString, Is.EqualTo("Hello World"));
22+
}
23+
}

src/TestUtils/src/UITest.Appium/HelperExtensions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,5 +2466,38 @@ public static void SetTestConfigurationArg(this IConfig config, string key, stri
24662466
startupArg.Add(key, value);
24672467
config.SetProperty("TestConfigurationArgs", startupArg);
24682468
}
2469+
2470+
/// <summary>
2471+
/// Gets the search handler element for the shell.
2472+
/// This method is used to find the search handler element in the app.
2473+
/// It uses different queries based on the app type (Android, iOS, Catalyst, or Windows).
2474+
/// </summary>
2475+
/// <param name="app">The IApp instance representing the application.</param>
2476+
/// <returns>The search handler element for the shell.</returns>
2477+
public static IUIElement GetShellSearchHandler(this IApp app)
2478+
{
2479+
IUIElement? element = null;
2480+
2481+
if (app is AppiumAndroidApp)
2482+
{
2483+
element = app.WaitForElement(AppiumQuery.ByXPath("//android.widget.EditText"));
2484+
}
2485+
else if (app is AppiumIOSApp || app is AppiumCatalystApp)
2486+
{
2487+
element = app.WaitForElement(AppiumQuery.ByXPath("//XCUIElementTypeSearchField"));
2488+
}
2489+
else if (app is AppiumWindowsApp)
2490+
{
2491+
element = app.WaitForElement("TextBox");
2492+
}
2493+
2494+
// Ensure the element is not null before returning
2495+
if (element is null)
2496+
{
2497+
throw new InvalidOperationException("SearchHandler element not found.");
2498+
}
2499+
2500+
return element;
2501+
}
24692502
}
24702503
}

0 commit comments

Comments
 (0)