title: How to hide WPF DataGrid rows programmatically
body: <p>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.</p>
  
  <p>Here's my strategy in pseudocode, I'm new to C#, .Net, and WPF, so feel very free to recommend alternative methods.</p>
  
  <pre><code>for each Row in DataGrid
      for each Column in Row
          if Cell doesn't contains SearchQuery
              hide Row
              break
  </code></pre>
  
  <p>In C#:</p>
  
  <pre><code>        List&lt;int&gt; rowsWithoutMatch = new List&lt;int&gt;();
  
          for (int i = 0; i &lt; dataGrid.Items.Count; i++)
          {
              DataGridRow row = (DataGridRow)dataGrid.
                                ItemContainerGenerator.ContainerFromIndex(i);
  
              if (row != null)
              {
                  for (int j = 0; j &lt; dataGrid.Columns.Count; j++)
                  {
                      DataGridCellsPresenter presenter = GetVisualChild&lt;DataGridCellsPresenter&gt;(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;
                              }
                          }
                      }
                  }
              }
          }
  </code></pre>
  
  <p>I was getting this weird error where <code>row != null</code> only for the first 24 iterations and it was all null after that so it stopped iterating through rows. </p>
  
  <p>I learned from <a href="https://stackoverflow.com/questions/6713365/itemcontainergenerator-containerfromitem-returns-null/6736301">this</a> 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.</p>
  
  <p>I fixed the problem by putting the tag <code>VirtualizingStackPanel.IsVirtualizing="False"</code> into the DataGrid XMAL, but now it loads all the rows at once and goes extremely slowly. Same with adding <code>dataGrid.UpdateLayout();
  dataGrid.ScrollIntoView(dataGrid.Items[i]);</code>, but that also has a few more bugs. </p>
  
  <p>I also tried this, which was faster</p>
  
  <pre><code>        dataGrid.DataContext = dt.AsDataView();
  
          for (int i = dt.Rows.Count - 1; i &gt;= 0; i--)
          {
              DataRow dr = dt.Rows[i];
  
              for (int j = 0; j &lt; columnFilters.Length; j++)
              {
                  if (! dr[j].ToString().Contains( columnFilters[j] ))
                  {
                      dr.Delete();
                      break ;
                  }
              }
          }
  
          dataGrid.DataContext = dt.AsDataView();
  </code></pre>
  
  <p>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. </p>
  
  <p>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.</p>
  
  <p>Thanks a lot.</p>