maui icon indicating copy to clipboard operation
maui copied to clipboard

SearchBar: Execute SearchCommand when .Text == ""

Open hujun-open opened this issue 2 years ago • 7 comments

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

hujun-open avatar Jul 25 '22 21:07 hujun-open

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.

Neralem avatar Sep 03 '22 11:09 Neralem

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.

DelphinRP avatar Sep 23 '22 08:09 DelphinRP

I also encountered this problem, which resulted in the unavailability of SearchBar

saber-wang avatar Oct 27 '22 09:10 saber-wang

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

tsquillario avatar Dec 09 '22 16:12 tsquillario

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.

ghost avatar Feb 04 '23 02:02 ghost

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);
        }

NicolaZuc avatar May 26 '23 09:05 NicolaZuc

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){ }
    }
}

Felicity-R avatar Jan 05 '24 01:01 Felicity-R