maui
maui copied to clipboard
SearchBar: Execute SearchCommand when .Text == ""
Description
currently SearchBar.SearchCommand is not executed when the text == "", however for use case where the SearchBar is used to filter what's display in a list (e.g. CollectionView), when user clear the search bar, it is expected to display the full list. however this can't be achieved currently using SearchCommand.
there is a workaround is to use TextChanged event, however it would be nicer to have SearchCommand also fired with empty string.
Public API Changes
API change is optional, maybe a knob to enable such behavior, but it is not mandatory from my point of view
Intended Use-Case
see the description above
The SearchCommand wasn't executed for me at all.
I've solved this by Binding the Text Property twoway to a string in my viewmodel. In the setter I trigger my search. So I'm not using the SearchCommand.
We're facing the same issue: In our application we expect an empty search text resulting in a display of all available data.
This works fine with MAUI running as a Windows application. However, at least with android emulator trying to trigger a search with an empty text does not execute the search command.
Current situation:
-
Windows: Pressing
Enter
on the keyboard always triggers SearchCommand. - Android Emulator: Clicking the search icon on the virtual keyboard triggers SearchCommand only if search text is not empty.
I also encountered this problem, which resulted in the unavailability of SearchBar
Ran into the same issue. @Neralem thanks! The added benefit is you don't have to hit Enter to search.
Not sure if this is the BEST way to do it, but it works!
<SearchBar x:Name="searchBar"
Placeholder="Search..."
Text="{Binding SearchText, Mode=TwoWay}"/>
In ViewModel
private string searchText;
public string SearchText
{
get
{
return searchText;
}
set
{
searchText = value;
if (searchText.Length > 2)
{
Task.Run(async () => { await Search(searchText); }).Wait();
}
if (searchText == "")
{
Task.Run(async () => { await Refresh(); }).Wait();
}
}
}
The Search function is a Command that updates the ObservableCollection which I have bound to a CollectionView ItemsSource
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Same issue here. My workaround:
xaml:
<SearchBar
x:Name="SearchBar"
Placeholder="Ricerca libera.."
TextChanged="SearchBar_TextChanged"
SearchCommand="{Binding SearchCommand}"
SearchCommandParameter="{Binding Source={x:Reference SearchBar}, Path=Text}" />
c#:
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(e.NewTextValue))
if (((SearchBar)sender).SearchCommand?.CanExecute(e.NewTextValue) == true)
((SearchBar)sender).SearchCommand?.Execute(e.NewTextValue);
}
If you want the search command to actually fire rather than using text changed, here's how I made it work by extending the SearchBarHandler:
internal class EnhancedSearchBarHandler : SearchBarHandler
{
private TextWatcher _watcher;
private EditText _editText;
protected override void ConnectHandler(SearchView platformView)
{
base.ConnectHandler(platformView);
_editText = PlatformView.GetChildrenOfType<EditText>().FirstOrDefault();
_watcher = new TextWatcher();
_editText.AddTextChangedListener(_watcher);
}
protected override void DisconnectHandler(SearchView platformView)
{
_editText.RemoveTextChangedListener(_watcher);
_watcher.Dispose();
base.DisconnectHandler(platformView);
}
private class TextWatcher : Java.Lang.Object, ITextWatcher
{
private const string _zeroWidthSpace = "\u200b";
public TextWatcher(){ }
public void AfterTextChanged(IEditable s)
{
if (string.IsNullOrEmpty(s.ToString()))
{
// Android search bar won't allow searching with an empty search term. Get around this
// by secretly adding an invisible character so it isn't technically empty.
s.Append(_zeroWidthSpace);
}
}
public void BeforeTextChanged(ICharSequence s, int start, int count, int after){ }
public void OnTextChanged(ICharSequence s, int start, int before, int count){ }
}
}