javascript
WPF:使用Json.NET在TreeView中树形显示JSON数据
原文?
WPF:使用Json.NET在TreeView中樹形顯示JSON數據
據
讀者可以參考這個開源的可以樹形顯示XML和JSON的工具:
Mgen Object 603:XML/JSON樹形顯示小工具
或者一個更大的開源工程(構建和分析HTTP并支持XML及JSON的樹形顯示):
Mgen Bluckbadda
?
效果如下:
(每一個項目中的左側黑字是數據的值,右側灰字是數據的類型。對于對象或數組,黑字會顯示對象的屬性個數或數組的成員個數)
(上圖中的JSON數據來自:http://www.jsonexample.com/?中的最下面的示例JSON)
?
具體實現方法是通過利用Json.NET中的Json對象基類:JToken類型,在Newtonsoft.Json.Linq命名空間內,這個類型的派生類型有:
?
JValue類型代表著一個Json數據值,也就是不會再有子節點的原子值。
而另一個JToken的直接繼承者是JContainer類型,代表數據對象有子節點,它的派生類型:JProperty,JObject和JArray分別代表屬性,對象和數組。
?
我最初想到的是用JToken類型的Type屬性來構建樹,但是隨后發現JTokenType的定義完全平面化,不利于不同類型成員結構的創建,于是采用直接判斷JToken對象類型的方式來構建樹。也就是直接根據不同JToken類型來生成其相應的成員節點數據。
?
整個樹的數據類型由一個類型來完成,名稱是JsonHeaderLogic,它定義三個屬性:
public?string?Header {?get;?private?set; }
public?IEnumerable<JsonHeaderLogic>?Children {?get;?private?set; }
public?JToken?Token {?get;?private?set; }
Header是當前節點的顯示文字。
Children是子節點。(如果沒有的話值是null)
Token是原始的Json.NET中的JToken對象。
?
那么在界面上,我們就可以直接使用WPF中TreeView和HierarchicalDataTemplate來這樣定義DataTemplate:
<TreeView?Name="treeView">
??? <TreeView.ItemTemplate>
??????? <HierarchicalDataTemplate?ItemsSource="{Binding?Children}">
??????????? <StackPanel?Orientation="Horizontal">
????????????????<!-- 顯示Header屬性 -->
??????????????? <TextBlock?Text="{Binding?Header}"/>
????????????????<!-- 顯示JToken的Type屬性 -->
??????????????? <TextBlock?Text="{Binding?Token.Type}"?Margin="10 0 0 0"?Foreground="Gray"/>
??????????? </StackPanel>
??????? </HierarchicalDataTemplate>
??? </TreeView.ItemTemplate>
</TreeView>
?
JsonHeaderLogic類型的完整定義:
//+ using Newtonsoft.Json.Linq;
class?JsonHeaderLogic
{
????//用于對應Json對象類型的格式化字符
????const?string?NULL_TEXT?=?"<null>";
????const?string?ARRAY?=?"[{0}]";
????const?string?OBJECT?=?"[{0}]";
????const?string?PROPERTY?=?"{0}";
?
????//用于界面綁定的屬性定義
????public?string?Header {?get;?private?set; }
????public?IEnumerable<JsonHeaderLogic>?Children {?get;?private?set; }
????public?JToken?Token {?get;?private?set; }
?
????//內部構造函數,使用FromJToken來創建JsonHeaderLogic
??? JsonHeaderLogic(JToken?token,?string?header,?IEnumerable<JsonHeaderLogic>?children)
??? {
??????? Token?=?token;
??????? Header?=?header;
??????? Children?=?children;
??? }
?
????//外部的從JToken創建JsonHeaderLogic的方法
????public?static?JsonHeaderLogic?FromJToken(JToken?jtoken)
??? {
????????if?(jtoken?==?null)
??????? {
????????????throw?new?ArgumentNullException("jtoken");
??????? }
?
????????var?type?=?jtoken.GetType();
?
????????if?(typeof(JValue).IsAssignableFrom(type))
??????? {
????????????var?jvalue?=?(JValue)jtoken;
????????????var?value?=?jvalue.Value;
????????????if?(value?==?null)
??????????????? value?=?NULL_TEXT;
????????????return?new?JsonHeaderLogic(jvalue, value.ToString(),?null);
??????? }
????????else?if?(typeof(JContainer).IsAssignableFrom(type))
??????? {
????????????var?jcontainer?=?(JContainer)jtoken;
????????????var?children?=?jcontainer.Children().Select(c?=>?FromJToken(c));
????????????string?header;
?
????????????if?(typeof(JProperty).IsAssignableFrom(type))
??????????????? header?=?String.Format(PROPERTY, ((JProperty)jcontainer).Name);
????????????else?if?(typeof(JArray).IsAssignableFrom(type))
??????????????? header?=?String.Format(ARRAY, children.Count());
????????????else?if?(typeof(JObject).IsAssignableFrom(type))
??????????????? header?=?String.Format(OBJECT, children.Count());
????????????else
????????????????throw?new?Exception("不支持的JContainer類型");
?
????????????return?new?JsonHeaderLogic(jcontainer, header, children);
??????? }
????????else
??????? {
????????????throw?new?Exception("不支持的JToken類型");
??????? }
??? }
}
?
定義好了JsonHeaderLogic類型,在相應界面事件后使用FromJToken方法來創建JsonHeaderLogic對象然后綁定到界面TreeView控件數據源就可以了:
//創建JObject
//textfile1.txt存儲著需要解析的JSON數據
var?jobj?=?JObject.Parse(System.IO.File.ReadAllText("textfile1.txt"));
//創建TreeView的數據源
treeView.ItemsSource?=?jobj.Children().Select(c?=>?JsonHeaderLogic.FromJToken(c));
?
?
源代碼下載?
下載地址?
注意:此為微軟SkyDrive存檔,請用瀏覽器直接下載,用某些下載工具可能無法下載?
示例程序運行環境:.NET Framework 4.0 Client Profile?
源代碼環境:Microsoft Visual Studio Express 2012 for Windows Desktop?
注意:源代碼不包含引用的外部類庫文件: Json.NET
總結
以上是生活随笔為你收集整理的WPF:使用Json.NET在TreeView中树形显示JSON数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: va_start、va_end、va_l
- 下一篇: 降息还是加息?