2017-01-08 23 views
0

我的應用程序處理很多返回JSON數據的HTTP請求。我使用JSON.NET庫來處理它。JSON.NET對象的數據綁定:如何實現?

我需要這些數據顯示在Winforms數據綁定控件(主要是ComboBoxDataGridView)。目前沒有數據編輯的意圖,只需要以用戶友好的方式顯示數據。

我寫的轉換IEnumerable(Of JToken)一個簡易的轉換例程到DataTable

Module JsonAsDataTable 
    <Runtime.CompilerServices.Extension> Public Function ToDataTable(ByVal jtokens As IEnumerable(Of JToken), Optional ByVal trim_object_columns As Boolean = False, Optional ByVal castToCLRtypes As Boolean = False, Optional ByVal orderBy As String = Nothing) As DataTable 
     Dim dt As New DataTable, sdt As DataTable, dr, sdr As DataRow, dateproperty As Date 
     If jtokens IsNot Nothing Then 
      For Each jt In jtokens 
       dr = dt.NewRow 
       For Each jp In jt.Children(Of JProperty) 
        sdt = Nothing 
        If Not dt.Columns.Contains(jp.Name) Then dt.Columns.Add(jp.Name, IIf(castToCLRtypes, GetType(Object), GetType(JToken))) 
        If jp.Value.Type = JTokenType.Object AndAlso jp.Value.Children.Count = 1 AndAlso jp.Value.First.Type = JTokenType.Property AndAlso DirectCast(jp.Value.First, JProperty).Name = "date" Then 
         If Date.TryParse(DirectCast(jp.Value.First, JProperty).Value, dateproperty) Then 
          dr.SetField(jp.Name, New JValue(dateproperty)) 
         Else 
          dr.SetField(jp.Name, JValue.CreateNull) 
         End If 
        Else 
         dr.SetField(jp.Name, jp.Value) 
         If jp.Value.Type = JTokenType.Object Then 
          sdt = AsDataTable({jp.Value}, trim_object_columns) 
         ElseIf jp.Value.Type = JTokenType.Array Then 
          sdt = AsDataTable(jp.Value, trim_object_columns) 
         End If 
         If sdt IsNot Nothing Then 
          sdr = sdt.Select.FirstOrDefault 
          For Each sdc As DataColumn In sdt.Columns 
           If Not dt.Columns.Contains(jp.Name & "." & sdc.ColumnName) Then dt.Columns.Add(jp.Name & "." & sdc.ColumnName, GetType(Object)) 
           If sdr IsNot Nothing Then dr.SetField(jp.Name & "." & sdc.ColumnName, sdr(sdc.ColumnName)) 
          Next 
          If trim_object_columns Then dt.Columns.Remove(jp.Name) 
         End If 
        End If 
       Next 
       dt.Rows.Add(dr) 
      Next 
      If castToCLRtypes Then 
       For Each drow In dt.Select 
        For Each dcol As DataColumn In dt.Columns 
         If TypeOf drow(dcol) Is JToken Then drow(dcol) = ToField(drow(dcol)) 
        Next 
       Next 
      End If 
      If dt.Rows.Count > 0 AndAlso Not String.IsNullOrEmpty(orderBy) Then 
       dt = dt.Select("", orderBy).CopyToDataTable 
      End If 
     End If 
     Return dt 
    End Function 
    <Runtime.CompilerServices.Extension> Friend Function ToField(token As JToken) As Object 
     If token Is Nothing Then Return Nothing 
     Select Case token.Type 
      Case JTokenType.Boolean 
       Return token.Value(Of Boolean) 
      Case JTokenType.Bytes 
       Return token.Value(Of Byte()) 
      Case JTokenType.Date 
       Return token.Value(Of Date) 
      Case JTokenType.Float 
       Return token.Value(Of Double) 
      Case JTokenType.Guid 
       Return token.Value(Of Guid) 
      Case JTokenType.Integer 
       Return token.Value(Of Integer) 
      Case JTokenType.Null 
       Return Nothing 
      Case JTokenType.Property 
       Return ExtractObjectFrom(CType(token, JProperty).Value) 
      Case JTokenType.String 
       Return token.Value(Of String) 
      Case JTokenType.TimeSpan 
       Return token.Value(Of TimeSpan) 
      Case JTokenType.Uri 
       Return token.Value(Of Uri) 
      Case Else 
       Return token.ToString 
     End Select 
    End Function 
End Module 

現在我知道我的解決方案是既不乾淨,也不可靠。這只是我爲了讓事情在DataGridView中顯示的第一件事情,用戶可以通過單擊列標題對數據進行排序,這種簡單的JToken Array不允許。

因此,我想編寫一個自定義類來包裝這些JToken對象,也許是一個Collection類,以DataGridView易於理解和處理的方式列出它們,從而實現排序等功能(這對我來說很重要)和篩選(這將成爲Achiev3e的額外獎勵)。

我的問題是:這是最小的一組接口這些類應實現,以實現這一目標?

回答

1

這並不是說容易實現的列的排序與通用類別等List<T>等。通常IList<T>ICollection<T>足以結合到自Collection側一個GridView。你的對象不需要實現任何接口在GridView中顯示。爲了排序,你可能需要ICompareable<T>。排序一個Collection的問題並不像對一個DataTable進行排序那麼簡單。 GridView組件在這裏很差。在這link你找到許多建議如何解決集合排序。這些示例是C#,但應該是可適應的。我希望這可以幫助你。