Vb.net 过滤不带数据源的DatagridView
我试图通过文本框通过代码过滤手动加载的datagridview。它不工作,它告诉我System.NullReferenceExceptionVb.net 过滤不带数据源的DatagridView,vb.net,filter,datagridview,restsharp,Vb.net,Filter,Datagridview,Restsharp,我试图通过文本框通过代码过滤手动加载的datagridview。它不工作,它告诉我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", D
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
我通过以下方式实现了这一目标。我已经创建了一个带有此gridview所需字段的datatable。不过,首先我在表单上创建了一个全局数据表
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))
在循环中,我没有使用datagridview的insert方法,而是用接收到的数据填充datatable
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
然后,我将生成的数据表映射到表单的全局数据表,以供以后使用。我已经将DataTable全局分配为DataGridView的数据源
Me.GridTable = dt
Me.Dgv_canciones.DataSource = Me.GridTable
最后,在TextBox的TextChanged事件中,我放置了一个条件,以便它仅在用户在文本字段中键入至少3个字符时进行搜索。如果您键入的较少,它将加载整个歌曲列表,如果您键入的较多,它将加载搜索结果
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
如果Me.Txt\u buscar.Text.Length>2,则
Dim campo作为字符串=“cancion”
尝试
Dim筛选器为String=String.Format(“[{0}]如“{1}%”,campo,Me.Txt_-buscar.Text)
GridTable.DefaultView.RowFilter=过滤器
特例
MessageBox.Show(“Coño,no puedo buscar!!!Vaya mierda de programmador estáhecho el Zeko!!!”&vbCrLf&vbCrLf&“Error:”&ex.Message,“Coño!!!”,MessageBoxButtons.OK,MessageBoxIcon.Error)
结束尝试
ElseIf Me.Txt_buscar.Text.Length<2则
DirectCast(Me.Dgv_canciones.DataSource,DataTable).DefaultView.RowFilter=String.Empty
如果结束
在这里,我给大家留下完整的修正和功能代码
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
公共类Frm\u cancions
Dim GridTable作为DataTable
私有子Frm_Canciones_Load(发送方作为对象,e作为事件参数)处理MyBase.Load
Me.Dgv_canciones.Rows.Clear()
Dim请求作为新请求(“canciones”,DataFormat.Json)
ClienteRest.Cabeceras(请求)
Dim响应=clientest.cliente.Get(请求)
将respuesta作为新的JObject(CType(jsoninvert.DeserializeObject(response.Content),JObject))
Dim dt作为新数据表
添加(“id”,GetType(字符串))
添加(“cancion”,GetType(字符串))
Add(“duracion”,GetType(String))
添加(“url”,GetType(字符串))
Add(“archivo”,GetType(String))
对于响应中的JToken标记,选择token(“数据”)
Dim song As Cancion=token.ToObject(属于Cancion)
dt.Rows.Add(song.id.ToString,song.getitulocompleto().ToString,song.duracion.ToString,song.url.ToString,song.archivo.ToString)
下一个
Me.GridTable=dt
Me.Dgv_canciones.DataSource=Me.GridTable
端接头
私有子Txt_buscar_TextChanged(发送者作为对象,e作为事件参数)处理Txt_buscar.TextChanged
如果Me.Txt_buscar.Text.Length>2,则
Dim campo作为字符串=“cancion”
尝试
Dim筛选器为String=String.Format(“[{0}]如“{1}%”,campo,Me.Txt_-buscar.Text)
GridTable.DefaultView.RowFilter=过滤器
特例
MessageBox.Show(“Coño,no puedo buscar!!!Vaya mierda de programmador estáhecho el Zeko!!!”&vbCrLf&vbCrLf&“Error:”&ex.Message,“Coño!!!”,MessageBoxButtons.OK,MessageBoxIcon.Error)
结束尝试
ElseIf Me.Txt_buscar.Text.Length<2则
DirectCast(Me.Dgv_canciones.DataSource,DataTable).DefaultView.RowFilter=String.Empty
如果结束
端接头
私有子Frm_Canciones_KeyDown(发送方作为对象,e作为KeyEventArgs)处理MyBase.KeyDown
如果e.KeyCode=Keys.Escape,则
我
如果结束
端接头
私有子Dgv_canciones_CellDoubleClick(发件人作为对象,e作为DataGridViewCellEventArgs)处理Dgv_canciones.CellDoubleClick
如果(Me.Dgv_canciones.CurrentRow.Index+1)
End Class您从未将数据表设置为DGV的数据源,因此
CType(Me.DGV_canciones.DataSource,DataTable)
不会给您带来太多的好处,您已经知道了。您没有显示JSON,但也有可能您可以直接反序列化到DataTable。问题是,如果datagridview是由带有insert方法的循环填充的,并且没有关联的数据源或DataTable,那么如何在文本框中仅显示与插入的文本匹配的行。使用可以描述所需值的类对象填充绑定列表
要在DGV中显示,请使用BindingList作为BindingSource的数据源,将BindingSource设置为DGV的数据源。使用BindingSource方法对DGV进行筛选、排序等。或者,填写一个数据表,它提供了相同的工具。控件只是表示器(表示数据的工具),而不是数据存储/处理工具。如果要高效地工作,需要将数据与视图分离。否则,就需要不断地寻找新的黑客。谢谢,@Jimi。我已经用你的最后一个例子做了。我刚刚发布了我应用的解决方案,它是100%功能性的。非常感谢你的贡献。好的。有一件事你必须改变:你不需要或者不想创建一个新的数据视图。删除此项:Dim FilterData As New DataView(Me.GridTable)
。使用DataTable.DefaultView
:例如dim filter=String.Format(…)DirectCast(Dgv_canciones.DataSource,DataTable)。DefaultView.RowFilter=filter
。要删除筛选器,只需DirectCast(Dgv_canciones.DataSource,DataTable)。DefaultView.RowFilter=string.empty
。或者,由于您存储了数据表,GridTable.DefaultView.RowFilter=filter
,这是同样的事情,因为您指向的是同一个对象。好吧,最后我选择了根据您的建议改进代码<代码>变暗过滤器为S