web-dev-qa-db-fra.com

Rechercher une ligne dans dataGridView en fonction de la colonne et de la valeur

J'ai un dataGridView qui a 3 colonnes: SystemId, FirstName, LastName qui est lié en utilisant des informations de base de données. Je voudrais mettre en évidence un certain rang, ce que je ferais en utilisant:

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

La ligne ID que je ne connais toutefois pas et la bindingsource ne cesse de changer, ainsi la ligne 10 pourrait être "John Smith" dans un cas mais pas même exister dans un autre (j'ai un filtre qui filtre la source en fonction de ce que l'utilisateur entre dans "joh" donnerait toutes les lignes où le prénom/nom contient "joh", donc ma liste peut aller de 50 noms à 3 en un clic). 

Je veux trouver un moyen de sélectionner une ligne en fonction de SystemId et d'un nombre correspondant. Je peux obtenir l'ID système en utilisant la méthode suivante:

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

Il ne me reste plus qu'à l'appliquer au sélecteur de rangée. Quelque chose comme dataGridView1.Columns ["SystemId"]. IndexOf (systemId} mais cela ne fonctionne pas (aucune méthode n'existe). Toute aide est grandement appréciée.

48
Lukas

Cela vous donnera l'index de ligne gridview pour la valeur:

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

Ou une requête LINQ

int rowIndex = -1;

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

        rowIndex = row.Index;

alors vous pouvez faire:

dataGridView1.Rows[rowIndex].Selected = true;
126
Habib

Les réponses ci-dessus ne fonctionnent que si AllowUserToAddRows est défini sur false. Si cette propriété est définie sur true, vous obtiendrez une NullReferenceException lorsque la boucle ou la requête Linq essaie de négocier la nouvelle ligne. J'ai modifié les deux réponses acceptées ci-dessus pour gérer AllowUserToAddRows = true.

Réponse de boucle: 

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;
        }
    }
}

Réponse LINQ:

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;
19
jaredbaszler

Ou vous pouvez utiliser comme ça. Cela peut être plus rapide.

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
user3390902

Essaye ça:

        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);
        }
2
vahid ghezelvand

Ceci s’appuie sur la réponse ci-dessus de Gordon - il ne s’agit pas entièrement de mon travail original ..__ Ce que j’ai fait a été d’ajouter une méthode plus générique à ma classe d’utilitaire statique.

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;
        }

Puis, quelle que soit la forme dans laquelle je souhaite l’utiliser, j’appelle la méthode en passant le DataGridView, le nom de la colonne et la valeur de recherche. Pour des raisons de simplicité, je convertis tout en chaînes pour la recherche, même s’il serait assez facile d’ajouter des surcharges pour spécifier les types de données.

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

Si vous voulez juste vérifier si cet élément existe:

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

Ceux qui utilisentWPF

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;
      }
}

si vous souhaitez obtenir les éléments de ligne sélectionnés après cela, l'extrait de code suivant est utile.

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 
0
Deepu Reghunath