Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LINQ to get DataGridView row index where first column has specific value

I'd like to get the index of a DataGridViewRow, where the value of its first column matches.

My code so far:

string SearchForThis = "test";

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

The compiler error:

Could not find an implementation of the query pattern for source type 'System.Windows.Forms.DataGridViewRowCollection'. 'Where' not found. Consider explicitly specifying the type of the range variable 'r'.

like image 351
jacobz Avatar asked Jun 06 '14 14:06

jacobz


1 Answers

DataGridViewRowCollection doesn't implement IEnumerable<T>, that is why you can't use LINQ, use Enumerable.Cast method.

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

Or with Query Syntax:

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

You will need to get a single result back from the collection, that is why I have used First, but remember if there are no items matching the criteria, it will throw an exception. To overcome that see the solution at the end of answer.

See: Enumerable.Cast<TResult> Method

The Cast<TResult>(IEnumerable) method enables the standard query operators to be invoked on non-generic collections by supplying the necessary type information. For example, ArrayList does not implement IEnumerable<T>, but by calling Cast<TResult>(IEnumerable) on the ArrayList object, the standard query operators can then be used to query the sequence.

(You can also use Enumerable.OfType method, that will ignore all those which are not DataGridViewRow, but with DataGridView, Cast is fine as well)

You can also use FirstOrDefault to get the row first and then get the index like:

int index = 0;
var item = dgv.Rows.Cast<DataGridViewRow>()
                    .FirstOrDefault(r => r.Cells[0].Value == (object)1);
if (item != null)
    index = item.Index;
like image 128
Habib Avatar answered Nov 22 '22 03:11

Habib