Xamarin: Search As You Type with Delay

download.jpgI have an Entry Textbox that searches as the user types. I don’t want the search on every letter, but rather wait 0.5 seconds between typing then search on what the current Query Text is. So as the user types the Query builds a string. That string is searched on every 0.5 seconds, not after every keystroke.

Let’s say the user types CANADA, here’s what happens:

C {WAIT}
CA {WAIT}
CAN  {Search}
CANA {WAIT}
CANAD {WAIT}
CANADA {SEARCH}

Here how:

In your XAML put a SearchBar with a Command (Behaviors):

<SearchBar Text="{Binding Query}" Placeholder="Search Address Book">
   <SearchBar.Behaviors>
      <behaviors:EventHandlerBehavior EventName="TextChanged">
	 <behaviors:InvokeCommandAction Command="{Binding RefreshCommand}" />
      </behaviors:EventHandlerBehavior>
    </SearchBar.Behaviors>
</SearchBar>

When the user types we store the Text in the Model’s Query property and call the RefreshCommand in the model for changes. This is a common way to do searches.

Here’s the magic you need to put into your Model (thanks to SO)

public ICommand RefreshCommand => 
       new Command(async () => { 
     await DelayedQueryForKeyboardTypingSearches().ConfigureAwait(false); });
private CancellationTokenSource throttleCts = new CancellationTokenSource();
/// <summary>
/// Runs in a background thread, checks for new Query and runs current one
/// </summary>
private async Task DelayedQueryForKeyboardTypingSearches()
{
  try
   {
     Interlocked.Exchange(ref this.throttleCts, new CancellationTokenSource()).Cancel();
      await Task.Delay(TimeSpan.FromMilliseconds(500), this.throttleCts.Token)
	.ContinueWith(async task => await Refresh()  , 
                  CancellationToken.None, 
                  TaskContinuationOptions.OnlyOnRanToCompletion, 
                  TaskScheduler.FromCurrentSynchronizationContext());
	}
	catch  
	{
		//Ignore any Threading errors
	}
    }
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s