In my C# WPF application I have a DataGrid
and right above it there is a TextBox
for the user to search and filter the grid as they type. If the user types fast though, no text will appear until 2 seconds after they type because the UI thread is too busy updating the grid.
Since most of the delay is all on the UI side (i.e. filtering the datasource is nearly instant, but rebinding and re-rendering the grid is slow), multi-threading has not been helpful. I then tried setting the dispatcher of just the grid to be at a lower level while the grid gets updated, but this didn't solve the issue either. Here's some code... Any suggestions on how to solve this type of problem?
string strSearchQuery = txtFindCompany.Text.Trim();
this.dgCompanies.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(delegate
{
//filter data source, then
dgCompanies.ItemsSource = oFilteredCompanies;
}));
Using a ListCollectionView as your ItemsSource for the grid and updating the Filter works much faster than re-assigning the ItemsSource.
The example below filters 100000 rows with no apparent lag by simply refreshing the View in the setter for the search term text property.
ViewModel
class ViewModel
{
private List<string> _collection = new List<string>();
private string _searchTerm;
public ListCollectionView ValuesView { get; set; }
public string SearchTerm
{
get
{
return _searchTerm;
}
set
{
_searchTerm = value;
ValuesView.Refresh();
}
}
public ViewModel()
{
_collection.AddRange(Enumerable.Range(0, 100000).Select(p => Guid.NewGuid().ToString()));
ValuesView = new ListCollectionView(_collection);
ValuesView.Filter = o =>
{
var listValue = (string)o;
return string.IsNullOrEmpty(_searchTerm) || listValue.Contains(_searchTerm);
};
}
}
View
<TextBox Grid.Row="0" Text="{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}" />
<ListBox ItemsSource="{Binding ValuesView}"
Grid.Row="1" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With