72

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.

default locale
  • 13,035
  • 13
  • 56
  • 62
Lukas
  • 2,885
  • 2
  • 29
  • 31

9 Answers9

182

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;
F.zehra
  • 87
  • 8
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 3
    this saved really much of my time, in my opinion the best way is linq method.. :D – Berker Yüceer Apr 22 '14 at 13:13
  • I'd go for a clean cast of the DataBoundItem to your ViewModel and have a comparison at its property directly... then you don't depend on column names. Nevertheless, the solution I went for, thanks! – Kjellski Jul 08 '15 at 08:43
  • Thanks for this solution- very easy to implement. Only change I made was to do `DGV.Rows[row.Index].Selected = true; break;` to save a line – elmer007 Mar 17 '16 at 21:55
  • 2nd Attempt at comment: For me there was no movement with the select statement above. Found elsewhere (Alex Filipovici) dgvIcbSubsInfo.CurrentCell = dgvIcbSubsInfo.Rows[currentRow].Cells[0]; – Bob Clegg Dec 20 '16 at 20:26
27

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;
Gordon Mackie JoanMiro
  • 3,499
  • 3
  • 34
  • 42
jaredbaszler
  • 3,941
  • 2
  • 32
  • 40
  • 3
    I am a few years too late, but better late than never I suppose. :) giving you a +1 because of the discovery. – Lukas Apr 13 '15 at 17:33
2

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." );
2

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);
        }
Ilija Dimov
  • 5,221
  • 7
  • 35
  • 42
1

If you just want to check if that item exists:

IEnumerable<DataGridViewRow> rows = grdPdfs.Rows
            .Cast<DataGridViewRow>()
            .Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue));
if (rows.Count() == 0) 
{
    // Not Found
} 
else 
{
    // Found
}
Rodrigo Boratto
  • 1,053
  • 13
  • 13
1

This builds on the above answer from Gordon--not all of it is my original work. What I did was add a more generic method to my static utility class.

public static int MatchingRowIndex(DataGridView dgv, string columnName, string searchValue)
        {
        int rowIndex = -1;
        bool tempAllowUserToAddRows = dgv.AllowUserToAddRows;

        dgv.AllowUserToAddRows = false; // Turn off or .Value below will throw null exception
        if (dgv.Rows.Count > 0 && dgv.Columns.Count > 0 && dgv.Columns[columnName] != null)
            {
            DataGridViewRow row = dgv.Rows
                .Cast<DataGridViewRow>()
                .FirstOrDefault(r => r.Cells[columnName].Value.ToString().Equals(searchValue));

            rowIndex = row.Index;
            }
        dgv.AllowUserToAddRows = tempAllowUserToAddRows;
        return rowIndex;
        }

Then in whatever form I want to use it, I call the method passing the DataGridView, column name and search value. For simplicity I am converting everything to strings for the search, though it would be easy enough to add overloads for specifying the data types.

private void UndeleteSectionInGrid(string sectionLetter)
        {
        int sectionRowIndex = UtilityMethods.MatchingRowIndex(dgvSections, "SectionLetter", sectionLetter);
        dgvSections.Rows[sectionRowIndex].Cells["DeleteSection"].Value = false;
        }
Joey Morgan
  • 823
  • 6
  • 9
0

Those who use WPF

for (int i = 0; i < dataGridName.Items.Count; i++)
{
      string cellValue= ((DataRowView)dataGridName.Items[i]).Row["columnName"].ToString();                
      if (cellValue.Equals("Search_string")) // check the search_string is present in the row of ColumnName
      {
         object item = dataGridName.Items[i];
         dataGridName.SelectedItem = item; // selecting the row of dataGridName
         dataGridName.ScrollIntoView(item);                    
         break;
      }
}

if you want to get the selected row items after this, the follwing code snippet is helpful

DataRowView drv = dataGridName.SelectedItem as DataRowView;
DataRow dr = drv.Row;
string item1= Convert.ToString(dr.ItemArray[0]);// get the first column value from selected row 
string item2= Convert.ToString(dr.ItemArray[1]);// get the second column value from selected row 
Deepu Reghunath
  • 8,132
  • 2
  • 38
  • 47
0
string text = "param";

var rows = dataGridViewlist.Rows.OfType<DataGridViewRow>()
                                 .Select(x => new { Value = x.Cells[6].Value.ToString(), Index = x.Index }).ToList();

var index= rows.Where(w => w.Value == text).Select(s => s.Index).FirstOrDefault();
  • When I tried to display the index and rows on MessageBox, nothing was shown (even the messagebox itself does not appears) – Henry Davis Sep 21 '22 at 14:27
0

You can try:

string DT = string.Empty;
try
 {
   DT = $"{dataGridView1.SelectedRows[0].Cells[1].Value}-{dataGridView1.SelectedRows[0].Cells[2].Value}-{dataGridView1.SelectedRows[0].Cells[3].Value}-{dataGridView1.SelectedRows[0].Cells[4].Value}";
 }
catch { }

try
 {
   dataGridView1.Rows.Cast<DataGridViewRow>().Where(x => $"{x.Cells[1].Value}-{x.Cells[2].Value}-{x.Cells[3].Value}-{x.Cells[4].Value}" == DT).ToList()[0].Selected = true;
 }
catch (Exception ex) { }
Sydney_dev
  • 1,448
  • 2
  • 17
  • 24
Tiago
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 01 '23 at 02:18