Reputation: 6266
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.
Screenshot of the page with filter.
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
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
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