json 文件搜索并在 datagridview 中找到输出
json file search with output found in datagridview
表单有一个文本字段和一个数据网格视图。需要在DataGridView中不显示json文件的全部内容,搜索json文件并在DataGridView.You中显示搜索结果需要通过UserName标签进行搜索.您需要开始在文本字段中输入名字或姓氏,然后在数据网格视图中显示找到的结果
我知道如何在dataGridView中读取文本文件:
Imports System.IO
Imports Newtonsoft.Json
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim result = JsonConvert.DeserializeObject(Of List(Of Users))(File.ReadAllText("D:\Users.json"))
DataGridView1.DataSource = result
End Sub
Public Class Users
Public Property ID() As Integer
Public Property UserName() As String
Public Property Login() As String
Public Property Title() As String
Public Property Dep() As String
Public Property Mail() As String
Public Property Phone() As String
End Class
End Class
我也知道如何进行文件搜索。仅出于某种原因显示结果 - 找到的第一个元素:
Dim json As String = File.ReadAllText("D:\Users.json")
Dim objectList = JsonConvert.DeserializeObject(Of List(Of Users))(json)
Dim foundItem = objectList.Where(Function(underscore) underscore.UserName.Contains("Tom")).FirstOrDefault()
If foundItem IsNot Nothing Then
MessageBox.Show(foundItem.UserName)
Else
MsgBox("none")
End If
以及 json 文件本身的实际内容:
[
{
"id":"1",
"UserName":"Fred Smith",
"Login":"f.smith",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"f.smith@domain.com",
"Phone":"111",
},
{
"id":"2",
"UserName":"Ben Taylor",
"Login":"b.taylor",
"Title":"programmer",
"Dep":"IT infrastcomcture",
"Mail":"b.taylor@domain.com",
"Phone":"100",
},
{
"id":"3",
"UserName":"Steve Harris",
"Login":"s.harris",
"Title":"System Administrator",
"Dep":"IT infrastcomcture",
"Mail":"s.harris@domain.com",
"Phone":"263",
},
{
"id":"4",
"UserName":"Tom Walker",
"Login":"t.walker",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"t.walker@domain.com",
"Phone":"263",
},
{
"id":"5",
"UserName":"Tom Davis",
"Login":"t.davis",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"t.davis@domain.com",
"Phone":"200",
},
{
"id":"6",
"UserName":"Ben Walker",
"Login":"b.walker",
"Title":"System Administrator",
"Dep":"IT infrastcomcture",
"Mail":"b.walker@domain.com",
"Phone":"167",
},
]
注意几点:
- 此处显示的 JSON 表示一组具有相同属性的对象。它可以被认为是 records 或 Rows.
的数组
- 您需要对此 JSON 进行反序列化,在 DataGridView 中显示结果并允许用户过滤并可能对数据进行排序。
您当前正在将此 JSON 反序列化为简单的集合 a class 对象,这完全没问题。如果你想过滤和排序这个集合,它可能会变得有点复杂,因为简单的 List<T>
本身不支持它。 BindingList 也没有。
您应该在基础 class 中实现 IBindingListView interface in a class that handles the List of objects and most probably also the INotifyPropertyChanged 接口(您当前的 Users
class)。
或者改用 ORM / Mini-ORM。
有一个已经构建(并经过测试)的类型已经实现了所有这些功能,DataTable class。
因为,如前所述,您的 JSON 实际上是一个 Table( 记录 的数组),因此将其反序列化为 DataTable 非常简单。只是:
Dim dt = JsonConvert.DeserializeObject(Of DataTable)(json)
数据Table class 已经允许过滤,设置其DefaultView.RowFilter property and sorting, setting its DefaultView.Sort 属性.
尽管如此,我建议在数据Table和UI之间使用BindingSource作为中介。
这个工具非常有用,因为它提供了对数据源进行筛选和排序的常用方法,前提是数据源实际上具有这些功能。
使用 BindingSource,无论数据源是什么,您始终使用相同的方法。
它还会生成一些有用的事件,如 ListChanged, AddingNew, CurrentChanged 事件等等。
ListChanged
事件还提供指定更改类型的参数。
使用 BindingSource,序列化回 JSON,如果数据已更改:
[BindingSource].EndEdit()
Dim json = JsonConvert.SerializeObject([BindingSource].DataSource, Formatting.Indented)
在示例代码中,使用了这些对象(参见可视化示例):
UsersSource
: BindingSource 对象
tBoxFilterUser
:TextBox控件,使用UserName
属性 过滤数据
tBoxFilterTitle
:TextBox控件,使用Title
属性 过滤数据
btnRemoveFilter
: 用于移除当前过滤器的按钮控件
dgv
: 一个 DataGridView 控件
Public Class SomeForm
Private UsersSource As New BindingSource()
' Current filters
Private UserNameFilter As String = "UserName LIKE '%%'"
Private UserTitleFilter As String = "Title LIKE '%%'"
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim json = File.ReadAllText("D:\Users.json")
Dim dt = JsonConvert.DeserializeObject(Of DataTable)(json)
dt.AcceptChanges()
UsersSource.DataSource = dt
dgv.DataSource = UsersSource
End Sub
Private Sub tBoxFilterUser_TextChanged(sender As Object, e As EventArgs) Handles tBoxFilterUser.TextChanged
Dim tbox = DirectCast(sender, TextBox)
UserNameFilter = $"UserName LIKE '%{tbox.Text}%'"
UsersSource.Filter = $"{UserNameFilter} AND {UserTitleFilter}"
End Sub
Private Sub tBoxFilterTitle_TextChanged(sender As Object, e As EventArgs) Handles tBoxFilterTitle.TextChanged
Dim tbox = DirectCast(sender, TextBox)
UserTitleFilter = $"Title LIKE '%{tbox.Text}%'"
UsersSource.Filter = $"{UserNameFilter} AND {UserTitleFilter}"
End Sub
Private Sub btnRemoveFilter_Click(sender As Object, e As EventArgs) Handles btnRemoveFilter.Click
tBoxFilterUser.Clear()
tBoxFilterTitle.Clear()
UsersSource.RemoveFilter()
End Sub
End Class
这是它的工作原理:
表单有一个文本字段和一个数据网格视图。需要在DataGridView中不显示json文件的全部内容,搜索json文件并在DataGridView.You中显示搜索结果需要通过UserName标签进行搜索.您需要开始在文本字段中输入名字或姓氏,然后在数据网格视图中显示找到的结果
我知道如何在dataGridView中读取文本文件:
Imports System.IO
Imports Newtonsoft.Json
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim result = JsonConvert.DeserializeObject(Of List(Of Users))(File.ReadAllText("D:\Users.json"))
DataGridView1.DataSource = result
End Sub
Public Class Users
Public Property ID() As Integer
Public Property UserName() As String
Public Property Login() As String
Public Property Title() As String
Public Property Dep() As String
Public Property Mail() As String
Public Property Phone() As String
End Class
End Class
我也知道如何进行文件搜索。仅出于某种原因显示结果 - 找到的第一个元素:
Dim json As String = File.ReadAllText("D:\Users.json")
Dim objectList = JsonConvert.DeserializeObject(Of List(Of Users))(json)
Dim foundItem = objectList.Where(Function(underscore) underscore.UserName.Contains("Tom")).FirstOrDefault()
If foundItem IsNot Nothing Then
MessageBox.Show(foundItem.UserName)
Else
MsgBox("none")
End If
以及 json 文件本身的实际内容:
[
{
"id":"1",
"UserName":"Fred Smith",
"Login":"f.smith",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"f.smith@domain.com",
"Phone":"111",
},
{
"id":"2",
"UserName":"Ben Taylor",
"Login":"b.taylor",
"Title":"programmer",
"Dep":"IT infrastcomcture",
"Mail":"b.taylor@domain.com",
"Phone":"100",
},
{
"id":"3",
"UserName":"Steve Harris",
"Login":"s.harris",
"Title":"System Administrator",
"Dep":"IT infrastcomcture",
"Mail":"s.harris@domain.com",
"Phone":"263",
},
{
"id":"4",
"UserName":"Tom Walker",
"Login":"t.walker",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"t.walker@domain.com",
"Phone":"263",
},
{
"id":"5",
"UserName":"Tom Davis",
"Login":"t.davis",
"Title":"engineer",
"Dep":"IT infrastcomcture",
"Mail":"t.davis@domain.com",
"Phone":"200",
},
{
"id":"6",
"UserName":"Ben Walker",
"Login":"b.walker",
"Title":"System Administrator",
"Dep":"IT infrastcomcture",
"Mail":"b.walker@domain.com",
"Phone":"167",
},
]
注意几点:
- 此处显示的 JSON 表示一组具有相同属性的对象。它可以被认为是 records 或 Rows. 的数组
- 您需要对此 JSON 进行反序列化,在 DataGridView 中显示结果并允许用户过滤并可能对数据进行排序。
您当前正在将此 JSON 反序列化为简单的集合 a class 对象,这完全没问题。如果你想过滤和排序这个集合,它可能会变得有点复杂,因为简单的 List<T>
本身不支持它。 BindingList 也没有。
您应该在基础 class 中实现 IBindingListView interface in a class that handles the List of objects and most probably also the INotifyPropertyChanged 接口(您当前的 Users
class)。
或者改用 ORM / Mini-ORM。
有一个已经构建(并经过测试)的类型已经实现了所有这些功能,DataTable class。
因为,如前所述,您的 JSON 实际上是一个 Table( 记录 的数组),因此将其反序列化为 DataTable 非常简单。只是:
Dim dt = JsonConvert.DeserializeObject(Of DataTable)(json)
数据Table class 已经允许过滤,设置其DefaultView.RowFilter property and sorting, setting its DefaultView.Sort 属性.
尽管如此,我建议在数据Table和UI之间使用BindingSource作为中介。
这个工具非常有用,因为它提供了对数据源进行筛选和排序的常用方法,前提是数据源实际上具有这些功能。
使用 BindingSource,无论数据源是什么,您始终使用相同的方法。
它还会生成一些有用的事件,如 ListChanged, AddingNew, CurrentChanged 事件等等。
ListChanged
事件还提供指定更改类型的参数。
使用 BindingSource,序列化回 JSON,如果数据已更改:
[BindingSource].EndEdit()
Dim json = JsonConvert.SerializeObject([BindingSource].DataSource, Formatting.Indented)
在示例代码中,使用了这些对象(参见可视化示例):
UsersSource
: BindingSource 对象tBoxFilterUser
:TextBox控件,使用UserName
属性 过滤数据
tBoxFilterTitle
:TextBox控件,使用Title
属性 过滤数据
btnRemoveFilter
: 用于移除当前过滤器的按钮控件dgv
: 一个 DataGridView 控件
Public Class SomeForm
Private UsersSource As New BindingSource()
' Current filters
Private UserNameFilter As String = "UserName LIKE '%%'"
Private UserTitleFilter As String = "Title LIKE '%%'"
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim json = File.ReadAllText("D:\Users.json")
Dim dt = JsonConvert.DeserializeObject(Of DataTable)(json)
dt.AcceptChanges()
UsersSource.DataSource = dt
dgv.DataSource = UsersSource
End Sub
Private Sub tBoxFilterUser_TextChanged(sender As Object, e As EventArgs) Handles tBoxFilterUser.TextChanged
Dim tbox = DirectCast(sender, TextBox)
UserNameFilter = $"UserName LIKE '%{tbox.Text}%'"
UsersSource.Filter = $"{UserNameFilter} AND {UserTitleFilter}"
End Sub
Private Sub tBoxFilterTitle_TextChanged(sender As Object, e As EventArgs) Handles tBoxFilterTitle.TextChanged
Dim tbox = DirectCast(sender, TextBox)
UserTitleFilter = $"Title LIKE '%{tbox.Text}%'"
UsersSource.Filter = $"{UserNameFilter} AND {UserTitleFilter}"
End Sub
Private Sub btnRemoveFilter_Click(sender As Object, e As EventArgs) Handles btnRemoveFilter.Click
tBoxFilterUser.Clear()
tBoxFilterTitle.Clear()
UsersSource.RemoveFilter()
End Sub
End Class
这是它的工作原理: