Introduction
Filter data is one among many important functionalities that users may want to have in a Website. You can imagine a case in witch a user needs to know every thing about his sales turnover related to a given product(s) by week, by month, by trimester, by semester or even during a given period. In this case we have two alternatives.
Alternative one
- Build an SQL request (in a data base case for e.g.: Oracle,SQL server, Access) and parameter the ADO objects such as connection and command conforming to this request.
- Use Xpath or/and XSLT transformation or/and others like objects in System.Xml namespace to get output data from XML files
Alternative two
Set the either the BindingSource or DataView object as a DataGridView data source and then use, respectively, either the Filter ( ) or RowFilter( ) method, and that can be applied in both situations, I mean either the data source is a data base or an XML/XSL file.
To explain how to do this I invite you to follow those steps
For this tutorial we use the Products table of the Northwind Database sample that you can download from the Microsoft official web site, you can even use another data source, never mind, because the procedure is the same.
First of all you create a new Windows application:
- Open the IDE Visual Studio 2005 for e.g
- Select File --> New Project --> Visual C# --> Windows --> WindowsApplication
- Name the project and click OK
- Drag and drop a DataGridView into the Form1
- Rename the DataGidView for e.g myGridView
- Drag and drop a Label control into the Form1 and change its text property to Products list from the minimum price to
- Drag and drop a combo box into the Form 1 and rename it for e.g PriceCombo
The Form1 will appear as below

Once the Form1 design is done, implement the Form1_load(Object sender, EventArgs e) as follow:
BindingSource use case:
BindingSource myBindingSource;
DataSet myDataSet;
private void Form1_Load(object sender, EventArgs e)
{
using (SqlConnection oConnection = new SqlConnection(/*Parameter the connectionstring recording to the personal data
source, for my case I use*/"Data Source = STANDARD;Initial Catalog = Northwind; Integrated Security = true"))
{
SqlCommand oCommand = new SqlCommand("Select Products.* From Products", oConnection);
SqlDataAdapter oAdapter = new SqlDataAdapter(oCommand);
myDataSet = new DataSet();
oAdapter.Fill(myDataSet);
}
myBindingSource = new BindingSource();
myBindingSource.DataSource = myDataSet;
myBindingSource.DataMember = myDataSet.Tables[0].TableName;
myGridView.DataSource = myBindingSource;
}
When you fire up the application all data in the table Products appear in the data grid view. Now, If you want to filter data by price interval for e.g. Populate the Price combo with some prices, you can even bind it to a given data source but in order to simplify the deal, one is satisfied quite simply to do the first alternative. So fill it with those values 0, 10, 20, 30, 50 for e.g.
Now, double click on the Price combo and implement its PriceCombo_SelectedIndexChanged(object sender, EventArgs e) with the following code:
private void PriceCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (PriceCombo.Text == "0") myBindingSource.Filter = "UnitPrice <= 0";
if (PriceCombo.Text == "10") myBindingSource.Filter = "UnitPrice <= 10";
if (PriceCombo.Text == "20") myBindingSource.Filter = "UnitPrice <= 20";
if (PriceCombo.Text == "30") myBindingSource.Filter = "UnitPrice <= 30";
if (PriceCombo.Text == "50") myBindingSource.Filter = "UnitPrice <= 50";
}
DataView use case
Rem: If DataView control doesn't appear in the Tool box, select Choose Tool Box in Tools menu, then select the .Net Framework Components tab. You can find DataView component there, select it and click OK.

DataView myDataView;
DataSet myDataSet;
private void Form1_Load(object sender, EventArgs e)
{
using (SqlConnection oConnection = new SqlConnection("Data Source = STANDARD;Initial Catalog = Northwind; Integrated
Security = true "))
{
SqlCommand oCommand = new SqlCommand("Select Products.* From Products", oConnection);
SqlDataAdapter oAdapter = new SqlDataAdapter(oCommand);
myDataSet = new DataSet();
oAdapter.Fill(myDataSet);
}
myDataView = new DataView();
myDataView.Table = myDataSet.Tables[0];
myGridView.DataSource = myDataView;
}
When you run the application all data appear as in the previous case. Now, If you want to filter data by price interval. Populate the Price combo with some values 10, 30, 50, 70, 90 for e.g.
Now double click on the Price combo and implement its PriceCombo_SelectedIndexChanged(object sender, EventArgs e) as mentioned below:
private void PriceCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (PriceCombo.Text == "0") myDataView.RowFilter = "UnitPrice <= 0";
if (PriceCombo.Text == "10") myDataView.RowFilter = "UnitPrice <= 10";
if (PriceCombo.Text == "20") myDataView.RowFilter = "UnitPrice <= 20";
if (PriceCombo.Text == "30") myDataView.RowFilter = "UnitPrice <= 30";
if (PriceCombo.Text == "50") myDataView.RowFilter = "UnitPrice <= 50";
}
Now, run the application and select value among those in the Price combo and you will remark that only products with prices inferior or equal to the value mentioned in the Combo price are listed and the others are hided.
For this example the price is choosen as a criteria of selection but you can choose whatever you want in terms of Data members such as ProductID, ProductName and others to create selection criteria.
Now, I give you some details and remarks about how to deal with the filter expression :
First of all let us say that all expressions used to filter data have string as format
- If the member type is string you must wrap the criteria value in quotation marks like this sample : "ProductID = 'PR0001k12'"
- If the member type is number you can write the expression like this "Maximum = 50"
- If the member has a name composed by two or more words that are separated by space, in a such case, you must wrap it in brakets [ ] like this sample: "[First Name] = 'Dihia' "
- If the member has a name that contains one of those characters \n (newline) \t (tab) \r (carriage return) ~ ( ) # \ / = > < + - * % & | ^ ' " [ ]
Those symbols are considered as special characters, so you must another once, as the example above I mean the third remark, wrap it in brakets [ ] like this sample: "[FirstName#] = 'Dihia' " - If the member name has this format xxx[ ],[ ]xxx or x[ ]xx, because the brakets are used here as special characters, you must use a slash ‘\' to escape the brakets as follow: "[First Name[\]] = 'Dihia' "
- If the member type is a date, in this case, you must wrap the criteria value in pound signs # such as "[Date of birth] = #11/04/78# ", the month at first, the day at second and the year at third position.
- You can combine more than one criteria at once by using AND,OR and NOT key words for example "(Maximum = 50 OR Minimum = 20) AND Weight = 30"
- You can use operators like =,<,>,<=,>=,IN,LIKE for example: "(Maximum = 50 OR Minimum > 20) AND [Product Name] LIKE 'Moster' "
- The arithmetic operators + - * / % can also be used as follow: "[Reduced Price] =[Original Price] * 1.2 "
- You can use agregate too, like Sum:Sum,Max:Maximum,Min:Minimum,Avg:Average,Var:Variance ,StDev:Standard deviation as follow "[Estimated Price] = (Price – Avg(Price))/StDev(Price)" if, of Corse, the statistic variable Price follows a stochastic process related to the normal standard Gauss' law.
These are the most importants methods that one can use in order to build a filter expression.

Sergio RodríguezPosted Nov 19, 2018, 7:36 AM
Hi, first thank you for this exellent article. I have a problem filtering while comparing two short dates ina datagridview.I need apply this filter "[FECHA_1] < [FECHA2]", it works well except when dates are in diferents years. For example, Fecha_1 = 03/01/2018 and Fecha_2 = 31/12/2017 is shown in the result filtered dataview.
PradeepPosted Mar 2, 2018, 9:08 AM
Hi, a related question. DataView.FindRows() returns an array, DataRowView[]. What is the most efficient way to bind that array to a DataGridView? Can it be done without iterating over each item in the array (I expect 1000s of items)? I'm looking for the fastest way to do this. Any help would be appreciated. Many thanks in advance
rsCodeeditedPosted Jan 2, 2012, 10:08 PMEdited Jan 2, 2012, 10:09 PM
Hi, Is It possible to apply Bindingsourc.filter result starting from 2nd row of datagridview? Because I have filteres in first row for each column to apply filter. Thanks
RajivPosted Sep 2, 2011, 10:45 PM
Thanks. Well explained
Jack YanPosted Apr 22, 2011, 5:35 AM
Good,I learn a lot from your article.thanks a lot.
Akash MahajanPosted Jun 30, 2010, 9:32 AM
thanks!
golocorbinPosted May 3, 2010, 12:38 PM
c# vs 2008 sql 2005 I have practice problem (days and days): I need dynamic filter for each row of DataGridView ! Example: dataGridView with two columns(0,1) types DataGridViewComboBoxCell which is wraped with two tables(A and B).Value from first column cause filtered second table in second column . _____ PK |---------------FK--------------------| | So : TableA (column 0) id TableB(column1) id id1 1 1 1 2 1 2 2 1 if column 0 have selected value 1 I wont have value options 1 and 2 if column 0 have selected value 2 I wont have value options 1 I try on event CellBeginEdit DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell) dataGridView [e.ColumnIndex, e.RowIndex]; tableB.DefaultView.RowFilter ="id="+dataGridView1.CurrentRow.Cells[0].Value.ToString(); cell.DataSource = delatnostvr.DefaultView; OR BindingSource link = new BindingSource(); link.Filter=............. cell.DataSource=link; Before edit I get OK filter for first row but after that dataGridView paint all grid and in the next row when formating column 1 value is not OK. I understand that the value in filtered B is not founded because filter.Every row mast have own filter I don't know how implement that ! I try with tableB.DefaultView.RowFilter ="" or link.RemoveFilter and after that I tray to change filter for the next row - result is always bad Across all dataGridView events and cell propertys DataView and BindingSource and ... I can't find good solution have anybody some idea ?
ItumelengPosted Apr 22, 2010, 5:24 AM
You saved me a few hours of figuring it out. It may be basic but it caught me out. Thanks
John RichardsPosted Apr 16, 2009, 12:40 PM
I have been trying to use the binding source method for several hours now and could not make it work properly. My problem was that I was enclosing the field name I was using, Meter Name, in single quotes, such as "'Meter Name' LIKE '%mx%'" and this would produce very odd results. Once I read comment number 3 at the bottom of your article and enclosed the field name in brackets, such as "[Meter Name] LIKE '%mx%'", it worked beautifully. Thanks for supplying me with the missing link.
Saravana VelPosted Mar 3, 2008, 1:30 AM
Thanks your niformation is very usefull...