winforms 搜索JSON文件的内容并在DataGridView中输出

g6baxovj  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(162)

Form具有文本字段和DataGridView,需要搜索JSON文件的内容并将搜索结果显示在DataGridView中,而不是在DataGridView中显示JSON文件的全部内容。
您需要按UserName标记进行搜索。您需要在文本字段中键入名字或姓氏,然后在DataGridView中显示找到的结果。
如何在DataGridView中读取文本文件我知道:

Imports System.IO
Imports Newtonsoft.Json

Public Class Form1

    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",
},
]
d8tt03nd

d8tt03nd1#

请注意以下几点:

  • 这里给出的JSON表示一个对象数组,这些对象都具有相同的属性。它可以被看作是一个 * 记录 * 或 * 行 * 的数组。
  • 您需要反序列化此JSON,在DataGridView中显示结果,并允许用户对数据进行筛选和排序。

您当前正在将此JSON反序列化为一个类对象的简单集合,这是非常好的。如果您想过滤和排序此集合,可能会变得稍微复杂一些,因为简单的List<T>本身不支持它,BindingList也不支持。
您应该在处理对象列表的类中实现IBindingListView接口,最有可能的是在基类(当前的Users类)中实现INotifyPropertyChanged接口。
或者使用ORM / Mini-ORM。
有一个已经构建(并测试)的类型,它已经实现了所有这些特性,即DataTable类。
正如前面提到的,由于JSON实际上是一个Table(records 的数组),因此将其反序列化为DataTable非常简单。

Dim dt = JsonConvert.DeserializeObject(Of DataTable)(json)

DataTable类别已经允许筛选(设定其DefaultView.RowFilter属性)和排序(设定其DefaultView.Sort属性)。
尽管如此,我还是建议使用BindingSource作为DataTable和UI之间的 * 中介 *。
这个工具非常有用,因为它提供了对数据源进行筛选和排序的常用方法,前提是数据源实际上具有这些功能。
使用BindingSource时,无论数据源是什么,您始终使用相同的方法。
它还生成一些有用的事件,如ListChangedAddingNewCurrentChanged事件等。
ListChanged事件也提供指定变更类型的参数。
使用BindingSource,如果数据已更改,则序列化回JSON:

[BindingSource].EndEdit()
Dim json = JsonConvert.SerializeObject([BindingSource].DataSource, Formatting.Indented)

在范例程式码中,会使用这些对象(请参阅视觉化范例):

  • UsersSource:绑定源对象
  • tBoxFilterUser:TextBox控件,使用UserName属性筛选数据
  • tBoxFilterTitle:TextBox控件,使用Title属性筛选数据
  • btnRemoveFilter:用于移除当前筛选器的Button控件
  • dgv:数据网格视图控件
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

它是这样工作的:

相关问题