Question: I want to perform a filter on a `DataGridView` using 3 different `TextBox`.
The solution below works, but does not consider very effective and good. Is there a way to improve it?

```
private void textBoxCod_TextChanged(object sender, EventArgs e)
{
    Filter();
}

private void textBoxArt_TextChanged(object sender, EventArgs e)
{
    Filter();
}

private void textBoxDesc_TextChanged(object sender, EventArgs e)
{
    Filter();
}

private void Filter()
{
    string queryFilter = "1=1"; //With this we avoid to check if there is the AND in the query
    var filterCod = textBoxCod.Text;
    var filterArt = textBoxArt.Text;
    var filterDescr = textBoxDesc.Text();
    if (filterCod != "")
        queryFilter += " AND product_code LIKE '%" + filterCod + "%'";
    if(filterArt != "")
        queryFilter += " AND article LIKE '%" + filterArt + "%'";
    if (filterDescr != "")
        queryFilter += " AND description LIKE '%" + filterDescr + "%'";

    bSource.Filter = queryFilter;
    dataGridView.DataSource = bSource;
}

```

Before I used the `string.Format` but I realized that not having optional parameters could not combine several filters.

Answer: 
You can remove the `1=1` hack by utilizing a collection of some sort, such as a `List<string>`, and `String.Join`.

Including braces with your if blocks aids readability.

You can avoid setting bindingSource filter if there are not actually any queries to run, and there is no need to reset the grids datasource:

```
    private void Filter()
    {
        var queries = new List<string>();
        //string queryFilter = "1=1"; //With this we avoid to check if there is the AND in the query

        var filterCod   = textBoxCod.Text;
        var filterArt   = textBoxArt.Text;
        var filterDescr = textBoxDesc.Text();

        if (filterCod != "")
        {
            queries.Add(String.Format("codice_prodotto LIKE '%{0}%'", filterCod));
        }

        if (filterArt != "")
        {
            queries.Add(String.Format("articolo LIKE '%{0}%'", filterArt));
        }

        if (filterDescr != "")
        {
            queries.Add(String.Format("descrizione_pt LIKE '%{0}%'", filterDescr));
        }

        if (queries.Count >= 1)
        {
            var queryFilter = String.Join(" AND ", queries);
            bSource.Filter = queryFilter;
            //dataGridView.DataSource = bSource;
        }

    }

```
Adding few improvements to @Steve's answer:

* It is always good to check for spaces(blanks): `if(!string.IsNullOrWhiteSpace(filterCod))`
* Wouldn't be nicer to have `queries.Any()` instead of `queries.Count >= 1` ?