2017-01-08 4 views
0

私のアプリケーションは、JSONデータを返すHTTPリクエストを多く扱っています。私はそれを処理するためにJSON.NETライブラリを使用します。JSON.NETオブジェクトのデータバインディング:実装方法

これらのデータはWinformsのデータバインディングコントロール(ほとんどComboBoxおよびDataGridView)に表示する必要があります。現時点ではデータの編集は意図されておらず、ユーザーフレンドリーな方法でデータを表示する必要があります。

私はDataTableIEnumerable(Of JToken)を変換即興変換ルーチンを書いた:

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オブジェクトをラップするカスタムクラス、およびおそらくDataGridViewがソートのような機能を有効にして処理する方法でそれらをリストするCollectionクラスを記述したいと思います(これは私には不可欠です)とフィルタリング(これは達成のための特別賞です)。

質問:最小限のインターフェイスのセットこれらのクラスは、これを実現するために実装する必要がありますか?

答えて

1

一般的なIList<T>またはICollection<T>コレクション側からのGridViewにバインドされるのに十分であるにList<T>などのような一般的なコレクションで列のソートを達成することは容易ではありません。オブジェクトは、GridViewに表示されるインタフェースを実装する必要はありません。並べ替えのために、おそらくICompareable<T>が必要です。問題は、コレクションをソートすることは、DataTableをソートするほど簡単ではないことです。ここでGridViewコンポーネントは非常に貧弱です。このlinkには、コレクションの並べ替えを解決する方法がたくさんあります。例はC#ですが、適応可能でなければなりません。私はこれがあなたを助けることを望む。

関連する問題