Парсинг Json; Запись данных в ветку TreeView

355
17 ноября 2017, 05:40

Я имею большой json файл, в котором данные расположены так:

  • id - id элемента
  • parent - id родителя
  • name - Имя

    ... { id: "2859", parent: "5853", name: " г. Москва" }, ...

Мне это нужно кинуть в TreeView. Помогите пожалуйста =(

Сейчас делаю это так:

...
private void getRegions()
    {
        var content = new WebClient { Encoding = Encoding.GetEncoding(1251) }.DownloadString("https://www.bicotender.ru/ajax/regiontree/?isSite=0");
        RootObject data = JsonConvert.DeserializeObject<RootObject>(content);
        foreach (var _data in data.data)
        {
            bool find = false;
            foreach(TreeNode n in Regions.Nodes)
            {
                if (n.Name == _data.parent)
                {
                    bool find2 = false;
                    n.Nodes.Add(_data.id, _data.name);
                    find = true;
                }
            }
            if (find != true)
            {
                Regions.Nodes.Add(_data.id, _data.name);
            }
        }
    }
...
public class Datum
{
    public string id { get; set; }
    public string parent { get; set; }
    public string name { get; set; }
}
public class RootObject
{
    public List<Datum> data { get; set; }
    public string status { get; set; }
}

Но, он делает это так:

Сам файл Json

Answer 1

Ошибка в том, что вы ищете родителя среди уже добавленных элементов, а они могут быть и позже.

Давайте для начала составим древовидную структуру. Для этого поменяем класс на такой:

public class Datum
{
    public int id { get; set; }     // <-- поменял на int
    public int parent { get; set; } // <-- поменял на int
    public string name { get; set; }
    public List<Datum> children;    // <-- добавил
}

Поле children не будет заполняться при чтении из JSON, но мы воспользуемся им потом.

Теперь, организуем наши элементы в дерево. И заодно вычислим корни — те элементы, у которых нет предков.

RootObject data = JsonConvert.DeserializeObject<RootObject>(content);
var list = data.data;
Dictionary<int, Datum> byId = list.ToDictionary(d => d.id);
List<Datum> roots = new List<Datum>();
// gather children
foreach (var datum in list)
{
    if (byId.TryGetValue(datum.parent, out Datum parent))
    {
        if (parent.children == null)
            parent.children = new List<Datum>();
        parent.children.Add(datum);
    }
    else
    {
        roots.Add(datum);
    }
}

Теперь наше заполнение выглядит как-то так:

FillRec(Regions.Nodes, roots);
void FillRec(TreeNodeCollection collection, List<Datum> content)
{
    foreach (var datum in content)
    {
        var child = collection.Add(datum.id.ToString(), datum.name);
        if (datum.children != null)
            FillRec(child.Nodes, datum.children);
    }
}
READ ALSO
Вывод двух графиков в chart C#

Вывод двух графиков в chart C#

Пытаюсь вывести два графика(series[0]-гистограмма, series[2]- график) и постоянно получаю такое "Проиндексированные ряды (XValueIndexed = true) невозможно отобразить...

473
Можно ли запустить AngleSharp в Parallel.Foreach()

Можно ли запустить AngleSharp в Parallel.Foreach()

Собственно сабжНужно вытащить содержимое определенного тэга

316
Как в .Net Core (c#) скрывать методы базового класса

Как в .Net Core (c#) скрывать методы базового класса

Сокрытие методовДелаю библиотеку классов (

335
Как получить заголовки или куки в awesomium?

Как получить заголовки или куки в awesomium?

Пробовал через javaScript получить куки

409