I'm using the following recursive function to try and render out an html accordion. It uses reflection to gather all property names and values of a given object. The object is a data tree structure of unknown depth/children etc.
@* 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);
}
}
}
My question is how would I go about rendering the html in a recursive way?
I have tried using a RenderFragment as follows :
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>;
}
It builds but gives an error on runtime :
Unhandled exception rendering component: Cannot bind to the target method because its signature is not compatible with that of the delegate type.
I know there must be an idiomatic way to do this in blazor but I can't wrap my head around how recursion would work with render fragments.