I have a DataGrid of about 2500 entries. I want the user to be able to do a search, and for rows that don't contain the search term to be hidden.
Here's my strategy in pseudocode, I'm new to C#, .Net, and WPF, so feel very free to recommend alternative methods.
for each Row in DataGrid
for each Column in Row
if Cell doesn't contains SearchQuery
hide Row
break
In C#:
List<int> rowsWithoutMatch = new List<int>();
for (int i = 0; i < dataGrid.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dataGrid.
ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
for (int j = 0; j < dataGrid.Columns.Count; j++)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
if (presenter != null)
{
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(j);
if (cell != null)
{
TextBlock tb = cell.Content as TextBlock;
string content = tb.Text;
if (!(content).Contains(columnFilters[j]))
{
row.Visibility = Visibility.Collapsed;
break;
}
}
}
}
}
}
I was getting this weird error where row != null
only for the first 24 iterations and it was all null after that so it stopped iterating through rows.
I learned from this SO question that it was because there were only 24 rows visible in the DataGrid, and the rows that weren't on screen were all null.
I fixed the problem by putting the tag VirtualizingStackPanel.IsVirtualizing="False"
into the DataGrid XMAL, but now it loads all the rows at once and goes extremely slowly. Same with adding dataGrid.UpdateLayout();
dataGrid.ScrollIntoView(dataGrid.Items[i]);
, but that also has a few more bugs.
I also tried this, which was faster
dataGrid.DataContext = dt.AsDataView();
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = dt.Rows[i];
for (int j = 0; j < columnFilters.Length; j++)
{
if (! dr[j].ToString().Contains( columnFilters[j] ))
{
dr.Delete();
break ;
}
}
}
dataGrid.DataContext = dt.AsDataView();
But I have a SQL DataBase connected to the DataGrid, and deleting rows became a huge problem. Plus, toggling visibility seemed like a better idea than messing around with the DataTable.
How could I make this go faster? Or even, what's an altogether different/better method of doing what I'm trying to? There seems a lot more options for windows forms for this sort of thing, but it's too late to change back from WPF.
Thanks a lot.