使用LINQ获取DataGridView行索引,其中第一列具有特定值。

7
我希望能够获取DataGridViewRow的索引,当第一列的值匹配时。

目前我的代码:

string SearchForThis = "test";

int index = from r in dgv.Rows
            where r.Cells[0].Value == SearchForThis
            select r.Index;

编译器错误:
找不到 'System.Windows.Forms.DataGridViewRowCollection' 类型的源类型的查询模式实现。未找到“Where”。请考虑明确指定范围变量“r”的类型。

尝试将dgv.Rows替换为dgv.Rows.Array,看看是否起作用? - Alex Barac
2个回答

14

DataGridViewRowCollection没有实现IEnumerable<T>接口,这就是为什么你不能使用LINQ的原因。请使用Enumerable.Cast方法。

int index = (dgv.Rows.Cast<DataGridViewRow>()
                    .Where(r => r.Cells[0].Value == SearchForThis)
                    .Select(r => r.Index)).First();

或者使用查询语法:

int index = (from r in dgv.Rows.Cast<DataGridViewRow>()
            where r.Cells[0].Value == SearchForThis
            select r.Index).First();

为了从集合中获取单个结果,我使用了First方法,但请记住如果没有符合条件的项,它会抛出异常。要克服这个问题,请参考答案末尾的解决方案。

查看:Enumerable.Cast<TResult> Method

Cast<TResult>(IEnumerable)方法通过提供必要的类型信息,使得标准查询运算符可以在非泛型集合上调用。例如,ArrayList没有实现IEnumerable<T>接口,但是通过在ArrayList对象上调用Cast<TResult>(IEnumerable)方法,标准查询运算符就可以用来查询序列。

(你也可以使用Enumerable.OfType方法,它将忽略不是DataGridViewRow的所有项,但是对于DataGridViewCast也可以使用)

您还可以使用FirstOrDefault方法先获取行,然后再获取索引,如下:

int index = 0;
var item = dgv.Rows.Cast<DataGridViewRow>()
                    .FirstOrDefault(r => r.Cells[0].Value == (object)1);
if (item != null)
    index = item.Index;

0

我通常喜欢这些表单,(尽管行不是一个合适的集合在语法上很烦人):

 var hit = dgv.Rows.Cast<DataGridViewRow>().First(row => row.Cells["MyColumnName"].Value.Equals(MyIndexValue));

 var hit = dgv.Rows.Cast<DataGridViewRow>().FirstOrDefault(row => row.Cells["MyColumnName"].Value.Equals(MyIndexValue));

如果你只想要第一个,那就更简单了:

 var hit = dgv.Rows.Cast<DataGridViewRow>().First(row => row.Cells[0].Value.Equals(MyIndexValue));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接