Enrico
Enrico

Reputation: 6266

Searchbar in MAUI doesn't fire the SearchCommand if the text is empty in iOS

In my ContentPage I have a SearchBar component. The ContentPage has a viewmodel that provides the Command.

<SearchBar x:Name="searchBar" BackgroundColor="white"
        SearchCommand="{Binding FilterCommand}"
        SearchCommandParameter="{Binding Source={x:Reference searchBar}, Path=Text}"
        Placeholder="Filter" />

In Windows and Android, when the user types a word and then Enter the application, as expected, calls the FilterCommand and the text of the SearchBar as parameter. If the user remove the text and press Enter, the app calls FilterCommand and the parameter is empty. Everything is working as I expected.

In iOS, the behaviour is different. When the user types a word and then Enter, the application calls FilterCommand with the text as a parameter. In the following screenshot you see the filter in action.

Screenshot of the page without filter.

enter image description here

Screenshot of the page with filter.

enter image description here

Now, if I remove the filter using the key delete or tap on the x at the end of the SearchBar or tap Cancel, the FilterCommand is not fired. I can press Enter but it doesn't fired.

Is there a specific command to invoke when the user clicks on one of this elements?

Upvotes: 0

Views: 1487

Answers (2)

Marco Ortali
Marco Ortali

Reputation: 163

If you just want a control that searchs when the user writes on the control and also searchs when the text clears here is the code. Just make a control that extends the searchbar and continue using it as normal. Also i've implemented the SearchCommandParameterProperty so you don't have to specify the text value as parameter as it's redundant.

public class SmartSearchBar : SearchBar
{
    public SmartSearchBar() : base()
    {
        var bnd = new Binding(nameof(this.Text), source: this);
        this.SetBinding(SmartSearchBar.SearchCommandParameterProperty, bnd);
    }
    
    protected override void OnTextChanged(string oldValue, string newValue)
    {
        if (this.SearchCommand?.CanExecute(newValue) == true)
            this.SearchCommand?.Execute(newValue);
        base.OnTextChanged(oldValue, newValue);
    }
}

Upvotes: 0

Peter Wessberg
Peter Wessberg

Reputation: 1921

I cannot reproduce that Android fires the FilterCommand when the Cancel is pressed. If the field is empty it shouldn't fire anything. Anyway. If you do want to take care of empty string and cancel I suggest MAUI ToolKit EventToCommandBehavior It is a very useful way to handle events in your ViewModel. It can look like this:

<SearchBar
    BackgroundColor="white"
    Placeholder="Filter"
    SearchCommand="{Binding FilterCommand}"
    SearchCommandParameter="{Binding Source={x:Reference self}, Path=Text}">
    <SearchBar.Behaviors>
        <toolkit:EventToCommandBehavior
            Command = "{Binding TextChangedCommand}"
            EventArgsConverter="{converters:TextChangedEventArgsConverter}"
            EventName="TextChanged" />
    </SearchBar.Behaviors>
</SearchBar>

You need to make a converter that takes care of SearchBar string value from the event

public class TextChangedEventArgsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var eventArgs = value as TextChangedEventArgs;
        return eventArgs?.NewTextValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And for sake of completeness a Command in the ViewModel

[RelayCommand]
private async Task TextChanged(string newText)
{
    if (string.IsNullOrEmpty(newText))
    {
        await Toast.Make("Searchbar is empty!").Show();
    }
    return;
}

Upvotes: 4

Related Questions