I want to present a list of up to 20 panels within a <MudExpansionPanels> component where the expanded child portion of each <MudExpansionPanel> is expensive to render. I tried the following test code but all instances of <LiveAgentSummary> are rendered as the parent is rendered, just to clarify this rendering of <LiveAgentSummary> happens before any panel is manually expanded.
<MudExpansionPanels>
@foreach (var liveAgent in _liveAgents)
{
<MudExpansionPanel [email protected]>
<LiveAgentSummary [email protected] />
</MudExpansionPanel>
}
</MudExpansionPanels>
I then looked into delaying the render of each <LiveAgentSummary> through use of a RenderFragment that is dynamically built during the <MudExpansionPanel> IsExpandedChanged event. However the event handler does not indicate which panel is being expanded and hence I do not know which liveAgent.Id param value to pass to <LiveAgentSummary> as I build a RenderFragment.
I think <MudExpansionPanels> is missing support for a bind-ActivePanelId property but hopefully I am overlooking an alternative solution to my delayed rendering objective.
This is the official MudBlazor example that prompted me to look into using a RenderFragment.
Update: A long answer briefly appeared yesterday suggesting that I could query the list of panel components on a built-in property that indicates the expanded state. The poster had gone to the trouble of reading the MudBlazor source code but the answer was then deleted.
I am now wondering how from code in an event handler it is possible to iterate over a component hierarchy declared as mark-up. Applying this to my example markup above, how could event handler code obtain a reference to each <MudExpansionPanel> child within <MudExpansionPanels>.
Can't you make use of the bool
from the IsExpandedChanged
callback? Something like this:
@page "/"
<MudExpansionPanels>
@foreach (var liveAgent in this.liveAgents)
{
<MudExpansionPanel
Text="@($"{liveAgent.Name} ({liveAgent.Data})")"
IsExpandedChanged="@(e => this.Load(e, liveAgent))">
<LiveAgentSummary Agent="@liveAgent" />
</MudExpansionPanel>
}
</MudExpansionPanels>
@code {
private readonly List<Agent> liveAgents = new()
{
new Agent("1", "Agent Smith"),
new Agent("2", "Agent Brown"),
new Agent("3", "Agent Jones")
};
private void Load(bool expanded, Agent agent)
{
if (expanded)
{
agent.Load();
}
}
}
<MudText>id: @this.Agent.Id, data: @this.Agent.Data</MudText>
@code {
[Parameter]
public Agent Agent { get; set; } = default!;
}
public record Agent(string Id, string Name)
{
public string Data { get; set; } = "Not loaded";
public void Load()
{
Console.WriteLine($"Loading agent {this.Id}...");
this.Data = "Loaded!";
}
}