使用 Blazor 渲染未知深度的树结构

Render tree structure of unknown depth using Blazor

我正在使用以下递归函数来尝试渲染 html 手风琴。 它使用反射来收集给定对象的所有 属性 名称和值。对象是未知的数据树结构depth/children等

@* Accordoin HTML Template *@
<div class="accordion">
  <input type="checkbox" id="accordion-1" name="accordion-checkbox" hidden>
   <label class="accordion-header" for="accordion-1">
    <i class="icon icon-arrow-right mr-1"></i>
    Title
   </label>
<div class="accordion-body">
    <!-- Accordions content -->
</div>
</div>

@code { 
public void BuildTree(object obj)
{
    if (obj == null) return;
    Type objType = obj.GetType();
    PropertyInfo[] properties = objType.GetProperties();
    foreach (PropertyInfo property in properties)
    {
        object propValue = property.GetValue(obj, null);
        if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
        {
            //Build accordion body
        }
        else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
        {
            //Build accordion header
            IEnumerable enumerable = (IEnumerable)propValue;
            if (enumerable != null)
                foreach (object child in enumerable)
                    BuildTree(child);
        }
        else
        {
            //Build accordion header
            BuildTree(propValue);
        }
    }
}

我的问题是如何以递归方式渲染 html?

我试过如下使用 RenderFragment :

RenderFragment BuildTree(object obj)
{
if (obj == null) return @<p>test</p>;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
    object propValue = property.GetValue(obj, null);
    if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
    {
       return @<p>Some test markup</p>
    }
    else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
    {
        IEnumerable enumerable = (IEnumerable)propValue;
        if (enumerable != null)
            foreach (object child in enumerable)
                BuildTree(child);
    }
    else
    {
        BuildTree(propValue);
    }
}
return @<p>Done</p>;
}

它构建但在运行时给出错误:

未处理的异常呈现组件:无法绑定到目标方法,因为它的签名与委托类型的签名不兼容。

我知道在 blazor 中必须有一种惯用的方法来执行此操作,但我无法理解递归如何与渲染片段一起工作。

我的2毛钱:组件可以自嵌套。对于我的大脑,这是呈现嵌套组件的最简单方法——一种非常物理的递归。我在工作,所以我无法为您完成一个可行的解决方案,但希望以下模板足够清晰。如果要显示所有分支,则完全放弃布尔逻辑或将 ShowChildren 初始化为 true 而不是 false;

Nestable.Razor

@if(ChildCollection is not null){
    <div @onclick=ToggleVisibility >
        <u>@DisplayForThisObject</u>
    </div>
     @if(ShowChildren){
         foreach (var Child in ChildCollection){
            <Nestable PassedObject=Child />
         }
     }
}
else {
    @DisplayForThisObject;
}

@code {
    [Parameter]
    public object PassedObject {get; set;}
    IEnumerable<object> ChildCollection {get; set;}
    string DisplayForThisObject {get; set;}
    bool ShowChildren {get; set;} = false;

    protected override void OnInitialized()
    {
        DisplayForThisObject = SomePropertyToString();
        ChildCollection = SomemethodToGetTheChildObjects(PassedObject);
        base.OnInitialized();
    }
    void ToggleVisibility(){
        ShowChildren = !ShowChildren;
    }
}