In our Blazor WebAssembly-App, we have a ParentComponent which nests multiple ChildComponents. There are 3 Files:
- Test.razor which is the client and uses the ParentComponent and ClientComponent.
- ParentComponent.razor which nests multiple ChildComponent.
- ChildComponent.razor which is a child-component of the ParentComponent.
File: Test.razor
<ParentComponent DataSource="@AccountList">
<ChildComponent TData="Account"><span>@context.FirstName</span></ChildComponent>
<ChildComponent TData="Account"><i>@context.LastName</i></ChildComponent>
<ChildComponent TData="Account"><b>@context.Age</b></ChildComponent>
</ParentComponent>
@code {
// The datasource:
private List<Account> AccountList = new List<Account>() {
new Account() { FirstName = "Sam", LastName = "Soldier", Age = 33},
new Account() { FirstName = "Lisa", LastName = "Johnson", Age = 25},
new Account() { FirstName = "Jonas", LastName = "Peer", Age = 50 }
};
// A Simple Account-Class for the datasource
class Account
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
}
The file above shows the following data as expected:
File: ParentComponent.razor
@typeparam TData
<CascadingValue Value="this" Name="ParentComponent">
@ChildContent
<div class="parent-component">
@foreach (var lData in DataSource)
{
@foreach (var lChild in m_Children)
{
<div class="child-component">
@lChild.ChildContent(lData);
</div>
}
}
</div>
</CascadingValue>
@code {
[Parameter]
public List<TData> DataSource { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
/// Collection of all added child components
private List<ChildComponent<TData>> m_Children = new List<ChildComponent<TData>>();
/// Add a child component (will be done by the child itself)
public void AddChildComponent(ChildComponent<TData> pChildComponent)
{
m_Children.Add(pChildComponent);
StateHasChanged();
}
}
File: ChildComponent.razor
@typeparam TData
@code {
/// Reference to the parent component
[CascadingParameter(Name = "ParentComponent")]
ParentComponent<TData> ParentComponent { get; set; }
/// Child content of the component.
[Parameter]
public RenderFragment<TData> ChildContent { get; set; }
// add ChildComponent to ParentComponent
protected override void OnInitialized()
{
Console.WriteLine("ChildComponent.OnInitialized");
ParentComponent.AddChildComponent(this);
}
}
Question: The file ParentComponent.razor contains the statement @ChildContent which makes no sense here, because we want to render the data of the children by @lChild.ChildContent(lData):
// [...]
<CascadingValue Value="this" Name="ParentComponent">
@ChildContent // <- required, but want to remove, because here is othing to show
<div class="parent-component">
@foreach (var lData in DataSource)
{
@foreach (var lChild in m_Children)
{
<div class="child-component">
@lChild.ChildContent(lData); // We wender the child here
</div>
}
}
// [...]
When we remove @ChildContent, then nothing will be rendered. So the invocation of @ChildContent seem to be required to render the child components, but seem to be unnecessary, because we call @lChild.ChildContent(lData);. How can we render the data without the statement @ChildContent?
Perhaps is there any invocation in the @code-block possible that does the same as @ChildContent? Example:
ParentComponent.razor:
@code {
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender)
{
ChildContent.Invoke(...); // ???
}
}
}

