Find a row in dataGridView based on column and value

I have a dataGridView that has 3 columns: SystemId, FirstName, LastName that is bound using database information. I would like to highlight a certain row, which I would do using:

dataGridView1.Rows[????].Selected = true;

The row ID I however do not know and the bindingsource keeps changing, thus row 10 could be "John Smith" in one instance but not even exist in another (I have a filter that filters out the source based on what user enters, so typing in "joh" would yield all rows where first / last name have "joh" in them, thus my list can go from 50 names to 3 in a click).

I want to find a way how I can select a row based on SystemId and a corresponding number. I can get the system ID using the following method:

systemId = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["SystemId"].Value.ToString();

Now I just need to apply it to the row selector. Something like dataGridView1.Columns["SystemId"].IndexOf(systemId} but that does not work (nor does such method exist). Any help is greatly appreciated.


This will give you the gridview row index for the value:

String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
    if(row.Cells[1].Value.ToString().Equals(searchValue))
    {
        rowIndex = row.Index;
        break;
    }
}

Or a LINQ query

int rowIndex = -1;

DataGridViewRow row = dgv.Rows
    .Cast<DataGridViewRow>()
    .Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
    .First();

rowIndex = row.Index;

then you can do:

dataGridView1.Rows[rowIndex].Selected = true;

The above answers only work if AllowUserToAddRows is set to false. If that property is set to true, then you will get a NullReferenceException when the loop or Linq query tries to negotiate the new row. I've modified the two accepted answers above to handle AllowUserToAddRows = true.

Loop answer:

String searchValue = "somestring";
int rowIndex = -1;
foreach(DataGridViewRow row in DataGridView1.Rows)
{
    if (row.Cells["SystemId"].Value != null) // Need to check for null if new row is exposed
    {
        if(row.Cells["SystemId"].Value.ToString().Equals(searchValue))
        {
            rowIndex = row.Index;
            break;
        }
    }
}

LINQ answer:

int rowIndex = -1;

bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;

dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception

    DataGridViewRow row = dgv.Rows
        .Cast<DataGridViewRow>()
        .Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue))
        .First();

    rowIndex = row.Index;

dgv.AllowUserToAddRows = tempAllowUserToAddRows;

Or you can use like this. This may be faster.

int iFindNo = 14;
int j = dataGridView1.Rows.Count-1;
int iRowIndex = -1;
for (int i = 0; i < Convert.ToInt32(dataGridView1.Rows.Count/2) +1; i++)
{
    if (Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value) == iFindNo)
    {
        iRowIndex = i;
        break;
    }
    if (Convert.ToInt32(dataGridView1.Rows[j].Cells[0].Value) == iFindNo)
    {
        iRowIndex = j;
        break;
    }
    j--;
}
if (iRowIndex != -1)
    MessageBox.Show("Index is " + iRowIndex.ToString());
else
    MessageBox.Show("Index not found." );

Try this:

        string searchValue = textBox3.Text;
        int rowIndex = -1;

        dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
        try
        {
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                if (row.Cells["peseneli"].Value.ToString().Equals(searchValue))
                {
                    rowIndex = row.Index;
                    dataGridView1.CurrentCell = dataGridView1.Rows[rowIndex].Cells[0];
                    dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Selected = true;

                    break;
                }
            }
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message);
        }