title: WPF Data-Bound Datagrid Filtering / Searching
body: <p>I have a WPF application which uses a (currently) local database to act as a binding source. Using the Visual Studio 2010 tools I have a LINQ-SQL model which acts as the Datacontext for most forms.</p>
  
  <p>What I have is a UserControl with a TextBox and Datagrid. The datagrid ItemSource is set upon the UserControl.Loaded event with a table. The TextBox has an event assigned so that a query is executed upon the database when the text changes and the ItemSource is updated upon the datagrid.</p>
  
  <p>The problem with this is the time it takes to query the database. As I'm reassigning the DataGrid itemsource for each search. </p>
  
  <ol>
  <li><p>Should I be loading all records upon the UserControl Loading - is there a way to load records asynchronously in a BackgroundWorker or similar?</p></li>
  <li><p>Do I need to reassign the DataGrid ItemsSource after each search or is their a more efficient way to filter the data?</p></li>
  </ol>
  
  <p>Thanks.
  Liam</p>
  
  <pre><code>&lt;UserControl x:Class="Tracker.DocumentsView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
               mc:Ignorable="d" 
               d:DesignHeight="300" d:DesignWidth="300"&gt;
      &lt;Grid&gt;
          &lt;DataGrid AutoGenerateColumns="False" Margin="12,34,12,50" Name="dataGrid1"&gt;
              &lt;DataGrid.Columns&gt;
                  &lt;DataGridTextColumn Binding="{Binding Path=ID}" Header="ID" /&gt;
                  &lt;DataGridTextColumn Binding="{Binding Path=Reference}" Header="Reference" /&gt;
                  &lt;DataGridTextColumn Binding="{Binding Path=Subject}" Header="Subject" /&gt;
              &lt;/DataGrid.Columns&gt;
          &lt;/DataGrid&gt;
  
          &lt;TextBox HorizontalAlignment="Left" Margin="64,8,0,0" Name="txtSearchBox" VerticalAlignment="Top" Width="224" TextChanged="txtSearchBox_TextChanged" /&gt;
          &lt;TextBlock Text="Search"  HorizontalAlignment="Left" Margin="11,12,0,0" Name="label1" VerticalAlignment="Top" Height="23" /&gt;
      &lt;/Grid&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>Code:</p>
  
  <pre><code>using System.Windows.Data;
  using System.Windows.Documents;
  using System.Windows.Input;
  using System.Windows.Media;
  using System.Windows.Media.Imaging;
  using System.Windows.Navigation;
  using System.Windows.Shapes;
  
  using Tracker.Model;
  
  namespace Tracker
  {
      /// &lt;summary&gt;
      /// Interaction logic for DocumentsView.xaml
      /// &lt;/summary&gt;
      public partial class DocumentsView : UserControl
      {
          private TrackerDataContext db;
  
          public DocumentsView()
          {
              InitializeComponent();
              this.Loaded += new RoutedEventHandler(DocumentsView_Loaded);
          }
  
          void DocumentsView_Loaded(object sender, RoutedEventArgs e)
          {
              db = new TrackerDataContext();
              dataGrid1.ItemsSource = db.Documents;
          }
  
          private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e)
          {
              TextBox textbox = sender as TextBox;
              if (textbox != null)
              {
                  string searchstr = textbox.Text;
                  if (!string.IsNullOrEmpty(searchstr))
                  {
                      var filtered = from document in db.Documents
                                     where document.Subject.Contains(searchstr)
                                         || document.Reference.Contains(searchstr)
                                     select document;
  
                      dataGrid1.ItemsSource = filtered;
                  }
                  else
                  {
                      dataGrid1.ItemsSource = db.Documents;
                  }
              }
          }
      }
  }
  </code></pre>