I'm trying to filter a manually loaded datagridview via code by a textbox. It doesn't work, it tells me System.NullReferenceException.
Private Sub Frm_Canciones_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Dgv_canciones.Rows.Clear()
Dim request As New RestRequest("canciones", DataFormat.Json)
ClienteRest.Cabeceras(request)
Dim response = ClienteRest.cliente.Get(request)
Dim respuesta As New JObject(CType(JsonConvert.DeserializeObject(response.Content), JObject))
For Each token As JToken In respuesta.SelectToken("data")
Dim song As Cancion = token.ToObject(Of Cancion)
Me.Dgv_canciones.Rows.Insert(Me.Dgv_canciones.NewRowIndex, song.id, song.getTituloCompleto(), song.duracion, song.url, song.archivo)
Next
End Sub
Private Sub Txt_buscar_TextChanged(sender As Object, e As EventArgs) Handles Txt_buscar.TextChanged
If Me.Txt_buscar.Text.Length > 3 Then
Dim campo As String = "cancion"
Try
CType(Me.Dgv_canciones.DataSource, DataTable).DefaultView.RowFilter = String.Format("[{0}] LIKE '%{1}%'", campo, Me.Txt_buscar.Text)
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "Error!!!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
I have achieved it in the following way. I have created a datatable with the fields that I need for this gridview. Although, firstly I have created a global DataTable on my form.
Dim dt As New DataTable
dt.Columns.Add("id", GetType(String))
dt.Columns.Add("cancion", GetType(String))
dt.Columns.Add("duracion", GetType(String))
dt.Columns.Add("url", GetType(String))
dt.Columns.Add("archivo", GetType(String))
In the loop, instead of using the insert method of the datagridview, I have filled the datatable with the received data.
For Each token As JToken In respuesta.SelectToken("data")
Dim song As Cancion = token.ToObject(Of Cancion)
dt.Rows.Add(song.id.ToString, song.getTituloCompleto().ToString, song.duracion.ToString, song.url.ToString, song.archivo.ToString)
Next
I have then mapped the resulting DataTable to my form's global DataTable for later use. And I have assigned as DataSource of the DataGridView the DataTable Global.
Me.GridTable = dt
Me.Dgv_canciones.DataSource = Me.GridTable
Finally, in the TextChanged event of the TextBox, I have placed a conditional so that it only searches if the user has typed at least 3 characters in the text field. If you have typed less, it loads the entire list of songs and if you have typed more it loads the search results.
If Me.Txt_buscar.Text.Length > 2 Then
Dim campo As String = "cancion"
Try
Dim filter As String = String.Format("[{0}] LIKE '%{1}%'", campo, Me.Txt_buscar.Text)
GridTable.DefaultView.RowFilter = filter
Catch ex As Exception
MessageBox.Show("Coño, no puedo buscar!!! Vaya mierda de programador está hecho el Zeko!!!" & vbCrLf & vbCrLf & "Error: " & ex.Message, "Coño!!!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
ElseIf Me.Txt_buscar.Text.Length < 2 Then
DirectCast(Me.Dgv_canciones.DataSource, DataTable).DefaultView.RowFilter = String.Empty
End If
And here I leave you the complete corrected and functional code.
Public Class Frm_Canciones
Dim GridTable As DataTable
Private Sub Frm_Canciones_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Dgv_canciones.Rows.Clear()
Dim request As New RestRequest("canciones", DataFormat.Json)
ClienteRest.Cabeceras(request)
Dim response = ClienteRest.cliente.Get(request)
Dim respuesta As New JObject(CType(JsonConvert.DeserializeObject(response.Content), JObject))
Dim dt As New DataTable
dt.Columns.Add("id", GetType(String))
dt.Columns.Add("cancion", GetType(String))
dt.Columns.Add("duracion", GetType(String))
dt.Columns.Add("url", GetType(String))
dt.Columns.Add("archivo", GetType(String))
For Each token As JToken In respuesta.SelectToken("data")
Dim song As Cancion = token.ToObject(Of Cancion)
dt.Rows.Add(song.id.ToString, song.getTituloCompleto().ToString, song.duracion.ToString, song.url.ToString, song.archivo.ToString)
Next
Me.GridTable = dt
Me.Dgv_canciones.DataSource = Me.GridTable
End Sub
Private Sub Txt_buscar_TextChanged(sender As Object, e As EventArgs) Handles Txt_buscar.TextChanged
If Me.Txt_buscar.Text.Length > 2 Then
Dim campo As String = "cancion"
Try
Dim filter As String = String.Format("[{0}] LIKE '%{1}%'", campo, Me.Txt_buscar.Text)
GridTable.DefaultView.RowFilter = filter
Catch ex As Exception
MessageBox.Show("Coño, no puedo buscar!!! Vaya mierda de programador está hecho el Zeko!!!" & vbCrLf & vbCrLf & "Error: " & ex.Message, "Coño!!!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
ElseIf Me.Txt_buscar.Text.Length < 2 Then
DirectCast(Me.Dgv_canciones.DataSource, DataTable).DefaultView.RowFilter = String.Empty
End If
End Sub
Private Sub Frm_Canciones_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Escape Then
Me.Close()
End If
End Sub
Private Sub Dgv_canciones_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles Dgv_canciones.CellDoubleClick
If (Me.Dgv_canciones.CurrentRow.Index + 1) < Me.Dgv_canciones.Rows.Count Then
Dim fPrograma As New Frm_programa
Helpers.currentCancion = New Cancion(Me.Dgv_canciones.Rows.Item(Me.Dgv_canciones.CurrentRow.Index).Cells.Item(0).Value)
Me.Close()
End If
End Sub
End Class