原文
<a href="http://www.cnblogs.com/mgen/archive/2013/01/04/2845015.html">據</a>
讀者可以參考這個開源的可以樹形顯示XML和JSON的工具:
<a href="http://www.cnblogs.com/mgen/archive/2013/01/16/2863430.html">Mgen Object 603:XML/JSON樹形顯示小工具</a>
或者一個更大的開源工程(建構和分析HTTP并支援XML及JSON的樹形顯示):
<a href="http://www.cnblogs.com/mgen/archive/2012/06/20/bluckbadda.html">Mgen Bluckbadda</a>
效果如下:
(每一個項目中的左側黑字是資料的值,右側灰字是資料的類型。對于對象或數組,黑字會顯示對象的屬性個數或數組的成員個數)
具體實作方法是通過利用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