2017-04-24 94 views
-1

对于C#和Visual Studio的新手来说,忍耐着我,建议做更好的事情都非常开放。在DataGridView中显示复杂的JSON

我想制作一个程序来使用DataGridView显示和编辑JSON。应用程序将从网上下载一些JSON(获得该部分),然后将其显示在应用程序中进行简单编辑,并在完成编辑后将其上载回服务器。问题是我在JSON显示的部分卡住了(可能是一个重要的部分)。

我发现我应该使用DataGridView来显示它(至少这是我从一些搜索得到的印象),我能够成功下载和反序列化JSON(使用JSON。 NET)使用一些简单的列表和字典。我希望能够将JSON反序列化为类,以便我能够更轻松地导航它,但使用我的嵌套字典和数组证明它非常困难。这里是一个示例(真正的文件有点长,但我已经剪掉了,所以你得到了要点)。

{ 
    "regular" : [ 
    [ 
     { 
     "description" : "Free E-Booklet", 
     "information" : "http://freeebooknotascam.com", 
     "contentType" : "banner", 
     "message" : "Free E-Booklet (NOT A SCAM!)", 
     "color" : "#811cca" 
     } 
    ], 
    [ 
     { 
     "description" : "Free Money!", 
     "information" : "http://freemoney.com", 
     "title" : "", 
     "contentType" : "web", 
     "thumbnail" : "http://freemoney.com/money" 
     } 
    ] 
    ], 
    "special" : [ 
    { 
     "description" : "Hats", 
     "information" : "", 
     "title" : "", 
     "contentType" : "web", 
     "thumbnail" : "http://hats.com/mlady" 
    }, 
    { 
     "description" : "Signup", 
     "information" : "", 
     "title" : "", 
     "contentType" : "web", 
     "thumbnail" : "http://google.com/signup/thumbnail.png" 
    } 
    ] 
} 

,因为他们出现,但JSON.NET并不想反序列化,并将其显示到DataGridView的我已经试过简单的类只用嵌套的列表和字典。

这是我目前使用的反序列化,它的工作原理,但它不显示在DataGridView(只显示计数,我不能遍历上下)。 JsonConvert.DeserializeObject<Result>(json);结果就是这样。

public class Result 
{ 
    public List<Dictionary<String, String>> featured; 
    public List<List<Dictionary<String, String>>> regular; 
} 

在一个视图我想列出的项目的标签description来回regular字典例如

- Regular 
    - Row One 
    - Free E-Booklet 
    - Row Two 
    - Free Money 

,并在其他将列出special字典

- Special 
    - Hats 
    - Signup 
+1

你有什么期望在'DataGridView'显示?它可以为你显示一个列表,所以你需要使用LINQ将结果形成一个合适的列表。 –

+0

@Reza Aghaei我想展示一个简单的列表,可以将其拖放到其他键/值中,但是现在只需要获得一个列出的字典数组并且列表中的描述键显示就没问题。 –

+1

最好在你的问题中包含所需输出的例子。此外,似乎您可以创建一个类而不是'Dictionary ',因为所有元素都具有相同的关键字 –

回答

1

我用了JavaScriptSerializer,但它并不重要。

由于字典中的密钥是不同的并且事先未知(如我所建议的),因此请使用DataTable。它允许您动态创建列。

var text = File.ReadAllText("file.txt"); 
var jss = new JavaScriptSerializer(); 
var root = (Dictionary<string, object>)jss.DeserializeObject(text); 

var data = root.SelectMany(pair => ((object[])pair.Value)); 

var dt = new DataTable(); 
dt.Columns.Add("special", typeof(bool)).ReadOnly = true; 

// regular 
foreach (var arr in data.OfType<object[]>()) 
    foreach (Dictionary<string, object> dict in arr) 
     foreach (var key in dict.Keys) 
      if (!dt.Columns.Contains(key)) 
       dt.Columns.Add(key); 

foreach (var arr in data.OfType<object[]>()) 
    foreach (Dictionary<string, object> dict in arr) 
    { 
     var row = dt.NewRow(); 
     foreach (var pair in dict) 
      row[dt.Columns[pair.Key]] = pair.Value; 
     dt.Rows.Add(row); 
    } 

// special 
foreach (var dict in data.OfType<Dictionary<string, object>>()) 
    foreach (var key in dict.Keys) 
     if (!dt.Columns.Contains(key)) 
      dt.Columns.Add(key); 

foreach (var dict in data.OfType<Dictionary<string, object>>()) 
{ 
    var row = dt.NewRow(); 
    row["special"] = true; 
    foreach (var pair in dict) 
     row[dt.Columns[pair.Key]] = pair.Value; 
    dt.Rows.Add(row); 
} 

dataGridView.DataSource = dt; 

为了表明哪一组 - 常规或特殊 - 行属于我,我添加了一个布尔列。相反,您可以使用两种不同的DataGridView

结果:

enter image description here

+0

之上添加了所需输出的粗略轮廓非常感谢!完美的作品。对于任何人在将来阅读这篇文章,你必须添加'使用System.Web.Script.Serialization;'和'使用System.Linq;'以便'JavaScriptSerializer'和'SelectMany'分别工作。 –