moClay
@moClay
учусь всему

Как заполнить treeview ( treenode ) данными из datatable?

У меня есть заполненная datatable экземплярами классов. В таблице есть столбы с названием Name и Name_of_Cement. Но в столбце Name есть повторяющиеся элементы. К примеру:
Name | Name_of_Cement
_________________|_____________________
Портланд | Вихрь
Романцемент | Тайга
Романцемент | Свой
Алумацемент | Курон

Подскажите как заполнить treeview ( treenode ) что бы выглядело примерно так, но с учетом того что таблица может дополняться одинаковыми Name

Цемент
|___Портланд
| |___Вихрь
|
|__Романцемент
| |___Тайга
| |
| |___ Свой
|
|__Алумацемент
| |___Курон

Кажется все костыли перепробовал и ничего не помогло. Буду благодарен ответу

P.S. Здесь сбиваются все отступы. Извините
  • Вопрос задан
  • 672 просмотра
Решения вопроса 3
yarosroman
@yarosroman Куратор тега C#
C# the best
Комментировать
FoggyFinder
@FoggyFinder
Можно преобразовать DataTable к строго типизированной коллекции с помощью метода AsEnumerable. Тогда вы сможете сделать группировку значений с помощью метода GroupBy.

После этого заполнить TreeView не составит труда.

Пример

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        var treeView = new TreeView
        {
            Dock = DockStyle.Fill
        };
        this.Controls.Add(treeView);

        var dt = GetDataTable();
        PopulateTreeViewFromDataTable(treeView, dt);
    }

    private DataTable GetDataTable()
    {
        var dt = new DataTable("Цемент");

        dt.Columns.AddRange(new[] {
            new DataColumn("Name"),
            new DataColumn("NameOfCement")
        });

        dt.Rows.Add("Портланд", "Вихрь");
        dt.Rows.Add("Романцемент", "Тайга");
        dt.Rows.Add("Романцемент", "Свой");
        dt.Rows.Add("Алумацемент", "Курон");

        return dt;
    }

    public void PopulateTreeViewFromDataTable(TreeView tv, DataTable dataTable)
    {
        var data =
            dataTable
                .AsEnumerable()
                .Select(row => new
                {
                    Name = row.Field<string>("Name"),
                    Cement = row.Field<string>("NameOfCement")
                })
                .GroupBy(x => x.Name);

        tv.Nodes.Clear();

        var root = tv.Nodes.Add(dataTable.TableName);
        foreach (var gr in data)
        {
            var node = root.Nodes.Add(gr.Key);
            foreach (var subItem in gr)
            {
                node.Nodes.Add(subItem.Cement);
            }
        }
    }
}


Результат

60856a498cd61836541563.jpeg
Ответ написан
Комментировать
moClay
@moClay Автор вопроса
учусь всему
Я нашел решение в том чтобы сначала заполнить родительскую ветвь всеми элементами
foreach (DataRow v in table.Rows)
            {
                node.Nodes[0].Nodes.Add(v[0].ToString());
            }


Затем пройтись по этим элементам и удалить повторяющиеся с помощью обычных циклов for ( до более рациональной штуки не додумался )

string x = " ";

for (int k = 0; k < node.Nodes[0.Nodes.Count; k++)
            {
                
                if (node.Nodes[0].Nodes[k].Text != x)
                {
                    x = node.Nodes[0].Nodes[k].Text;
                    
                }
                else
                {
                    node.Nodes[0].Nodes.Remove(node.Nodes[0].Nodes[k]);
                }
            }


И затем заполнил его элементами из второго столбца с помощью switch

foreach (DataColumn col in table.Columns)
            {
                if (col.ColumnName == "Name") 
                {
                    foreach (DataRow row in table.Rows)
                    {
                        switch (row[col.ColumnName].ToString())
                        {
                            case "Портланд":
                                node.Nodes[0].Nodes[r].Nodes.Add(row[1].ToString());
                                r++;
                                break;
                            case "Романцемент":
                                node.Nodes[0].Nodes[r].Nodes.Add(row[1].ToString());
                                break;
                            case "Алумацемент":
                                r++;
                                node.Nodes[0].Nodes[r].Nodes.Add(row[1].ToString());
                                break;
                        }
                    }               
                }
            }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы