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

淺唱寂寞╮ 提交于 2020-01-02 03:39:07

问题


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'.


回答1:


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;



回答2:


I generally like these forms, (although the fact that the Rows are not a proper collection is syntactically annoying):

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

If you only want the first one, it gets simpler:

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


来源:https://stackoverflow.com/questions/24083959/using-linq-to-get-datagridview-row-index-where-first-column-has-specific-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!