Вопрос по c# – Найти строку в dataGridView на основе столбца и значения

48

У меня есть dataGridView, который имеет 3 столбца: SystemId, FirstName, LastName, который связан с использованием информации базы данных. Я хотел бы выделить определенную строку, которую я бы сделал, используя:

<code>dataGridView1.Rows[????].Selected = true;
</code>

Однако идентификатор строки, который я не знаю, и источник привязки постоянно меняется, поэтому строка 10 может быть "John Smith" в одном случае, но даже не существует в другом (у меня есть фильтр, который отфильтровывает источник на основе того, что вводит пользователь, поэтому при вводе «joh» »будут получены все строки, в которых имя / фамилия содержит« joh », таким образом мой список может перейти от 50 имен до 3 в один клик).

Я хочу найти способ, как я могу выбрать строку на основе SystemId и соответствующего номера. Я могу получить системный идентификатор, используя следующий метод:

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

Теперь мне просто нужно применить его к селектору строк. Что-то вроде dataGridView1.Columns [& lt; SystemId & quot;]. IndexOf (systemId}, но это не работает (и такой метод не существует). Любая помощь очень ценится.

Те, кто используютWPF отослать этоlink Deepu Reghunath

Ваш Ответ

7   ответов
2

Попробуй это:

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

Это основано на приведенном выше ответе Гордона - не все это моя оригинальная работа. Что я сделал, так это добавил более общий метод к своему классу статических утилит.

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

Затем в любой форме, которую я хочу использовать, я вызываю метод, передающий DataGridView, имя столбца и значение поиска. Для простоты я конвертирую все в строки для поиска, хотя было бы достаточно легко добавить перегрузки для указания типов данных.

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

AllowUserToAddRows установлен вfalse, Если это свойство установлено вtrueтогда вы получитеNullReferenceException когда цикл или запрос Linq пытается согласовать новую строку. Я изменил два принятых ответа выше для обработкиAllowUserToAddRows = true.

Цикл ответа:

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 ответ:

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;
Я опоздал на несколько лет, но лучше поздно, чем никогда. :) давая вам +1 из-за открытия. Lukas
1

Если вы просто хотите проверить, существует ли этот элемент:

IEnumerable<DataGridViewRow> rows = grdPdfs.Rows
            .Cast<DataGridViewRow>()
            .Where(r => r.Cells["SystemId"].Value.ToString().Equals(searchValue));
if (rows.Count() == 0) 
{
    // Not Found
} 
else 
{
    // Found
}
Если вы просто хотите проверить наличие строк, используйте .Any ()
2

Или вы можете использовать как это. Это может быть быстрее.

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

Это даст вам индекс строки gridview для значения:

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

Или запрос LINQ

int rowIndex = -1;

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

        rowIndex = row.Index;

тогда вы можете сделать:

dataGridView1.Rows[rowIndex].Selected = true;
Спасибо за это решение - очень легко реализовать. Единственное изменение, которое я сделал, было сделатьDGV.Rows[row.Index].Selected = true; break; сохранить строку
Большое спасибо! Проверьте и upvote =) Lukas
2-я попытка в комментарии: для меня не было никакого движения с утверждением select выше. Найдено в другом месте (Алекс Филиповичи) dgvIcbSubsInfo.CurrentCell = dgvIcbSubsInfo.Rows [currentRow] .Cells [0];
Я пойду на чистую приведение DataBoundItem к вашей ViewModel и получу сравнение по его свойству напрямую ... тогда вы не будете зависеть от имен столбцов. Тем не менее, решение, которое я выбрал, спасибо!
это сэкономило мне много времени, по моему мнению, лучший способ это метод linq ..: D
0

Те, кто используют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;
      }
}

если вы хотите получить выбранные элементы строки после этого, полезен следующий фрагмент кода

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 

Похожие вопросы