等待ListBox完成渲染WPF

时间:2017-06-01 10:52:22

标签: c# wpf

我有一个ObservableCollection<Customer>(),出于测试目的,我有一个简单的for循环,可以添加2,000,000个带随机数的记录进行搜索。当我点击加载客户时,这显示了一个漂亮的微调器并且工作正常。

private async void button_Click(object sender, RoutedEventArgs e)
    {

        bool result = DatabaseMaster.CheckConnection(con);
        spinner.Visibility = Visibility.Visible;
        spinner.Spin = true;
        customers = await Task.Run(()=>DatabaseMaster.GetCustomers());
        customerListBox.ItemsSource = customers;
        spinner.Visibility = Visibility.Collapsed;
        spinner.Spin = false;
    }

但是,我有一个用于搜索的文本框,并希望搜索客户并更新视图。我试过了

await Task.Run(()=>customerListBox.ItemsSource = customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower())));

然而,这通过调用线程的错误无法访问此对象,因为另一个线程拥有它。

我尝试这个但是UI仍然会在更新项目源时跳转。任何想法或我应该了解更多inotifypropertychanged?

private async void search_TextChanged(object sender, TextChangedEventArgs e)
    {
        spinner.Visibility = Visibility.Visible;
        spinner.Spin = true;
        customerListBox.Background = Brushes.Gray;
        customerListBox.IsEnabled = false;
        await this.Dispatcher.BeginInvoke(new Action(() =>
         {
             customerListBox.ItemsSource = customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower()));
         }), null);
        customerListBox.Background = Brushes.White;
        customerListBox.IsEnabled = true;
        spinner.Visibility = Visibility.Collapsed;
        spinner.Spin = false;
    }

2 个答案:

答案 0 :(得分:2)

看起来customers只是一个本地集合。通常在另一个线程中查询它没有多大意义。但是,如果您仍然需要它,请确保仅在UI线程中使用UI对象(示例中为customerListBox)。

var text = searchTextBox.Text.ToLower();
var r = await Task.Run(() => customers.Where(X.name.ToLower().Contains(text).ToList());
customerListBox.ItemsSource = r;

答案 1 :(得分:0)

如果您将代码更改为以下它应该可以工作(因为itemsource将在ui线程中而不是在任务内部分配

customerListBox.ItemsSource = await Task.Run(()=> customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower())));
相关问题