Wpf toolkit AutoCompleteBox поиск в фоновом потоке - PullRequest
8 голосов
/ 31 декабря 2010

Я использую инструментарий WPF AutoCompleteBox, который его itemsSource представляет собой список миллионов объектов.

Использует ли AutoCompleteBox для поиска в фоновом потоке, а если нет, то как мне это сделать.

1 Ответ

13 голосов
/ 31 декабря 2010

Нет, он не использует фоновый поток. Вы можете прочитать исходный код в WPF Tookit . Однако он достаточно гибок, чтобы позволить вам сделать это самостоятельно в фоновом потоке.

Вы можете использовать этот подход:

  • Обработка события Populating: отмените его и запустите фонового работника, используя SearchText
  • Когда фоновый рабочий завершен: установите ItemsSource и позвоните PopulateComplete

Полный пример этого есть в документации MSDN:

В этом примере для заполнения данных автозаполнения используется асинхронный веб-сервис, но та же идея применима к поиску очень большого набора данных. Фоновая нить

Обновление:

Вот полный пример поиска в фоновом потоке. Включает односекундный сон для имитации длительного поиска:

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