Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wpf toolkit AutoCompleteBox search on background thread

I'm using WPF toolkit AutoCompleteBox that its itemsSource is a list of milions of objects.

Does the AutoCompleteBox use for the searching a background thread and if it doesn't how can I make it to.

like image 406
Erez Avatar asked Dec 30 '10 23:12

Erez


1 Answers

No, it does not use a background thread. You can read the source yourself in the WPF Tookit. However, it is flexible enough to allow you to do it yourself on a background thread.

You can use this approach:

  • Handle the Populating event: cancel it, and start your background worker using SearchText
  • When the background worker is complete: set the ItemsSource and call PopulateComplete

There is a complete example of this in the MSDN documentation:

  • AutoCompleteBox.Populating Event

That example uses a asynchronous web service to populate the auto-complete data but the same idea applies to searching a very large dataset. The background thread

Update:

Here is a complete example with the search occurring on a background thread. It includes a one-second sleep to simulate a long search:

private class PopulateInfo
{
    public AutoCompleteBox AutoCompleteBox { get; set; }
    public string SearchText { get; set; }
    public IEnumerable<string> Results { get; set; }
}

private void AutoCompleteBox_Populating(object sender, PopulatingEventArgs e)
{
    var populateInfo = new PopulateInfo
    {
        AutoCompleteBox = sender as AutoCompleteBox,
        SearchText = (sender as AutoCompleteBox).SearchText,
    };
    e.Cancel = true;
    var ui = TaskScheduler.FromCurrentSynchronizationContext();
    var populate = Task.Factory.StartNew<PopulateInfo>(() => Populate(populateInfo));
    populate.ContinueWith(task => OnPopulateComplete(task.Result), ui);
}

private PopulateInfo Populate(PopulateInfo populateInfo)
{
    var candidates = new string[] {
        "Abc",
        "Def",
        "Ghi",
    };
    populateInfo.Results = candidates
        .Where(candidate => candidate.StartsWith(populateInfo.SearchText, StringComparison.InvariantCultureIgnoreCase))
        .ToList();
    Thread.Sleep(1000);
    return populateInfo;
}

private void OnPopulateComplete(PopulateInfo populateInfo)
{
    if (populateInfo.SearchText == populateInfo.AutoCompleteBox.SearchText)
    {
        populateInfo.AutoCompleteBox.ItemsSource = populateInfo.Results;
        populateInfo.AutoCompleteBox.PopulateComplete();
    }
}
like image 112
Rick Sladkey Avatar answered Oct 06 '22 04:10

Rick Sladkey