根据列和值在dataGridView中查找一行
Posted
技术标签:
【中文标题】根据列和值在dataGridView中查找一行【英文标题】:Find a row in dataGridView based on column and value 【发布时间】:2012-04-28 02:00:45 【问题描述】:我有一个 dataGridView,它有 3 列:使用数据库信息绑定的 SystemId、FirstName、LastName。我想突出显示某一行,我会使用:
dataGridView1.Rows[????].Selected = true;
但是我不知道行 ID 并且绑定源不断变化,因此第 10 行在一个实例中可能是“John Smith”,但在另一个实例中甚至不存在(我有一个过滤器可以根据用户输入的内容过滤掉源,因此输入“joh”将产生所有名字/姓氏中包含“joh”的行,因此我的列表可以从 50 个名称变为单击 3 个)。
我想找到一种方法,如何根据 SystemId 和相应的数字选择行。我可以使用以下方法获取系统ID:
systemId = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["SystemId"].Value.ToString();
现在我只需要将它应用到行选择器。类似 dataGridView1.Columns["SystemId"].IndexOf(systemId 但不起作用(也不存在这种方法)。非常感谢任何帮助。
【问题讨论】:
那些使用 WPF 的人参考这个link 【参考方案1】:这将为您提供该值的 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;
【讨论】:
这确实节省了我很多时间,在我看来最好的方法是 linq 方法.. :D 我会将 DataBoundItem 干净地转换为您的 ViewModel 并直接对其属性进行比较...然后您就不必依赖列名了。不过,我所寻求的解决方案,谢谢! 感谢这个解决方案 - 非常易于实施。我所做的唯一更改是使用DGV.Rows[row.Index].Selected = true; break;
保存一行
第二次尝试评论:对我来说,上面的选择语句没有任何动作。在别处找到 (Alex Filipovici) dgvIcbSubsInfo.CurrentCell = dgvIcbSubsInfo.Rows[currentRow].Cells[0];【参考方案2】:
仅当AllowUserToAddRows
设置为false
时,上述答案才有效。如果该属性设置为true
,那么当循环或Linq 查询尝试协商新行时,您将获得NullReferenceException
。我已经修改了上面两个接受的答案来处理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。【参考方案3】:或者你可以这样使用。这可能会更快。
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." );
【讨论】:
【参考方案4】:试试这个:
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);
【讨论】:
【参考方案5】:如果您只想检查该项目是否存在:
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()【参考方案6】:这建立在 Gordon 的上述回答之上——并非所有这些都是我的原创作品。 我所做的是向我的静态实用程序类添加一个更通用的方法。
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;
【讨论】:
【参考方案7】:那些使用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;
如果你想在此之后获取选中的行项,下面的代码 sn -p 很有帮助
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
【讨论】:
以上是关于根据列和值在dataGridView中查找一行的主要内容,如果未能解决你的问题,请参考以下文章
Python:查找所有 6x6 矩阵,其中每个值在每列和每行中仅出现一次
如何在 C# 中使用 SqlCommand 读取每一行和值?