WPF: How to select a row of a datagrid via a search string on a column using view model model view pattern.

Published by Marian Galie-Andriescu on

This is a example on how to implement selecting a row in a datagrid based on a search string on a selected column.

We are using the MVVM pattern. Via the combobox the user can choose the column where the search will be performed:

Andriescu WPF DataGrid Search Row on Column MainWindow MVVM

The combobox will get its items directly from the data grid (named dgPersonList) as follows in xaml:

ItemsSource="{Binding Columns, ElementName=dgPersonList}"
DisplayMemberPath="Header"

The following xaml code will make sure that when the datagrid is losing focus the selected row will have textcolor red; therefore the selected row will still be visible for the user:

<DataGrid.Resources>
  <SolidColorBrush x:Key="{x:Static         SystemColors.InactiveSelectionHighlightTextBrushKey}"          Color="Red" />
</DataGrid.Resources>   

We are using an attached property called SelectingItemProperty for the datagrid to select the row into view:

  
grid.Dispatcher.InvokeAsync(() =>
{
  grid.UpdateLayout();
  if (grid.SelectedItem!=null)
    grid.ScrollIntoView(grid.SelectedItem, null);
});

Now the most interesting and complex part is how to search in a list of Persons (a person has properties FirstName, LastName, Classroom, and Number) based on the search string and the selected DataGridColumn from the Combobox.

First we read the column name via the binding of the DataGridTextColumn:

  
Binding aBinding = (Binding)
  (_selectedSearchColumn as DataGridTextColumn).Binding;
string personPropName = aBinding.Path.Path;

Then with reflexion we get the property of the person:

PropertyInfo prop = typeof(Person_M).GetProperty(personPropName);

Finally we can perform our search and select the row:

SelectedPerson = PersonList.First(p => prop.GetValue(p).ToString().ToLower().Contains(_searchString.ToLower()));

A tip about DataContext: If you declare the DataContext in xaml of the window via a resource as follows:

<Window.Resources>    
  <nameSpace:MainWindow_VM x:Key="DataContextMainWindow_VM" />
</Window.Resources>
<Window.DataContext>    
  <StaticResourceExtension ResourceKey="DataContextMainWindow_VM" />
</Window.DataContext>

then you can use it as a Static Resource. This is handy because sometimes you need to get data from the data context on a different level than you are currently in:

 
<Binding Path="SelectedPerson" 
         Source="{StaticResource DataContextMainWindow_VM}" />  

The project with full source code is available here:
Andriescu WPF DataGrid Select Row Example

Categories: .Net C#