web-dev-qa-db-ja.com

列と値に基づいてdataGridViewで行を見つける

データベース情報を使用してバインドされたSystemId、FirstName、LastNameの3つの列を持つdataGridViewがあります。特定の行を強調表示したいので、これを使用します:

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

ただし、行IDはわからず、bindingsourceは変化し続けるため、行10はあるインスタンスでは「John Smith」であるが、別のインスタンスには存在しないこともあります(ユーザーが入力した内容に基づいてソースをフィルターで除外するフィルターがあるため、 「joh」では、姓/名に「joh」が含まれるすべての行が生成されるため、1回のクリックでリストが50の名前から3に移動できます。

SystemIdと対応する番号に基づいて行を選択する方法を見つけたいです。次の方法を使用してシステムIDを取得できます。

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

次に、行セレクターに適用するだけです。 dataGridView1.Columns ["SystemId"]。IndexOf(systemId}のようなものですが、機能しません(そのようなメソッドも存在しません)。

52
Lukas

これにより、値の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;
135
Habib

上記の回答は、AllowUserToAddRowsfalseに設定されている場合にのみ機能します。そのプロパティがtrueに設定されている場合、ループまたはLinqクエリが新しい行をネゴシエートしようとすると、NullReferenceExceptionを取得します。 AllowUserToAddRows = trueを処理するために、上記の受け入れられた2つの回答を修正しました。

ループ回答:

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

または、このように使用できます。これはもっと速いかもしれません。

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

これを試して:

        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

これは、ゴードンからの上記の答えに基づいています。すべてが私のオリジナルの作品ではありません。私がしたことは、静的ユーティリティクラスに、より一般的なメソッドを追加することでした。

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;
        }
1
Joey Morgan

そのアイテムが存在するかどうかだけを確認したい場合:

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

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