分层列表 C# 上的编号项目

Numbering Item on Hierarchical List C#

我有一个 Element 类型的分层列表。每个 Element 都有一个 ParentElement 和一个 ChildElements.

的集合

我编写了一个递归 HTML 帮助程序来遍历分层列表并将每个元素打印到 table 行中。我希望能够根据层次列表中的位置标记 table 中的每个元素。例如

子结构没有子元素

上层建筑有 3 个 ChildElements - 上层、框架和屋顶

Upper Floors 和 Frame 没有子元素

屋顶有 2 个 ChildElements - 屋顶覆盖物和屋顶结构

我在调用递归助手的视图上有以下 HTML。

<table class="table table-bordered">
     <thead>
         <tr>
             <td>Reference</td>
             <td>Name</td>
         </tr>
     </thead>
     <tbody>
         @ShowTreeTable(Model.Elements, 1)
     </tbody>
</table>

递归助手如下

@helper ShowTreeTable(List<Entities.Entities.Element> elements, int level)
{
    for (int i = 0; i < elements.Count(); i++)
    {
        <tr>
            <td>@level</td>
            <td>@elements[i].Name</td>
        </tr>

        if (elements[i].ChildElements.Any())
        {
            @ShowTreeTable(elements[i].ChildElements.ToList(), level + 1)
        }
    }
}

我在尝试执行此操作时有一个更精细的助手,但它并不接近,所以我将其剥离回这个。

对于当前的例子,结果是这样的。

在将树放入视图之前,我通过在 C# 中操作树来实现它。

首先我得到根元素并将它们的引用 属性 设置为它们在列表中的位置 (+1)。

var roots = this.Elements.Where(x => !x.ParentElementId.HasValue).ToList();

this.Elements.Where(x => !x.ParentElementId.HasValue).ToList()
    .ForEach(x => x.Reference = (roots.IndexOf(x) + 1).ToString());

然后我写了另一个递归方法来更新所有子元素引用。棘手的部分是在给定自己的引用之前更新所有子父元素。如果没有这样做,所有子元素都包含对没有更新引用的父元素的引用。

private void ShowTree(List<Entities.Entities.Element> elements)
{
    for (int i = 0; i < elements.Count(); i++)
    {
        if (elements[i].ParentElementId.HasValue)
        {
            elements[i].Reference = $"{elements[i].ParentElement.Reference}.{i+1}";
        }

        if (elements[i].ChildElements.Any())
        {
            foreach (var child in elements[i].ChildElements)
            {
                 child.ParentElement = elements[i];
            }

            this.ShowTree(elements[i].ChildElements.ToList());
        }
    }
}

这与 OP 中的 HTML 代码相结合产生了正确的层次引用。