Ricerca in una DataGridView tramite Linq

Linq è un degli strumenti più duttili che si ha disposizione dal momento che il suo formalismo è applicabile ad ogni collezione.

Di conseguenza è possibile utilizzare Linq anche per eseguire query non solo rivolte ad ottenere dati da database, DataSet o Xml.

Nello specifico una situazione in cui Linq può tornare utile è quella di selezionare una o più DataGridViewRow di una DataGridView sulla base del valore contenuto nelle celle di una colonna.

Nell’esempio seguente riporto il codice per selezionare una DataGridViewRow ricercando il valore di una cella, nell’esempio ho ipotizzato che la cella contenga un ID univoco di tipo Integer e che quindi la query LInq non può che ritornare al massimo una DataGridViewRow

Dim row = (From r In Me.grdMain.Rows.Cast(Of System.Windows.Forms.DataGridViewRow)()
  Where CInt(r.Cells(Me.colID.Index).Value) = IDValue).SingleOrDefault()

If row IsNot Nothing Then
  row.Selected = True
End If

Si noti l’utilizzo del metodo Cast per far si che la query sulla collezione Rows ritorni oggetti tipo DataGridViewRow e non Object.

Il codice può poi essere utilizzato per creare un Extension Method che aggiunga agli oggetti  DataGridView un metodo FindRow e un metodo FindRows:

<System.Runtime.CompilerServices.Extension()> _
Public Function FindRow(ByVal grid As System.Windows.Forms.DataGridView, column As System.Windows.Forms.DataGridViewColumn, value As Object) As System.Windows.Forms.DataGridViewRow
    Return (From r In grid.Rows.Cast(Of System.Windows.Forms.DataGridViewRow)()
                 Where System.Object.Equals(r.Cells(column.Index).Value, value)).SingleOrDefault()
End Function

<System.Runtime.CompilerServices.Extension()> _
Public Function FindRows(ByVal grid As System.Windows.Forms.DataGridView, column As System.Windows.Forms.DataGridViewColumn, value As Object) As System.Collections.Generic.List(Of System.Windows.Forms.DataGridViewRow)
    Return (From r In grid.Rows.Cast(Of System.Windows.Forms.DataGridViewRow)()
                 Where System.Object.Equals(r.Cells(column.Index).Value, value)).ToList()
End Function

Per altri interessanti spunti si veda questo thead Linq to datagridview in VB.Net sui forum MSDN in lingua inglese.