C
C#•4mo ago
Pingu

Building a Blazor `RenderFragment` in base razor component to be used in derived?

Hey. So I have a base razor component that I want to derive from multiple times, as there will be a lot of duplicated code between the multiple derivations. One thing I have stumbled into, is that I have a title which is largely similar between all the derived components. For this, I currently have the following:
protected virtual string ObjectName => "Item";

protected RenderFragment TitleFragment() => builder =>
{
builder.OpenComponent<MudText>(0);
builder.AddAttribute(1, nameof(MudText.Typo), Typo.h6);
builder.AddAttribute(2, nameof(MudText.Class), "mr-10");

builder.AddAttribute(3, nameof(MudText.ChildContent), (RenderFragment) ((builder2) =>
{
builder2.OpenComponent<MudIcon>(4);
builder2.AddAttribute(5, nameof(MudIcon.Class), "mr-3 mb-n1");
if (IsCreating)
builder2.AddAttribute(6, nameof(MudIcon.Icon), Icons.Material.Filled.Add);
else
builder2.AddAttribute(6, nameof(MudIcon.Icon), Icons.Material.Filled.Edit);
builder2.CloseComponent();
if(IsCreating)
builder2.AddContent(7, $"Create {ObjectName}");
else
builder2.AddContent(7, $"Edit {ObjectName}");
}));
builder.CloseComponent();
};
protected virtual string ObjectName => "Item";

protected RenderFragment TitleFragment() => builder =>
{
builder.OpenComponent<MudText>(0);
builder.AddAttribute(1, nameof(MudText.Typo), Typo.h6);
builder.AddAttribute(2, nameof(MudText.Class), "mr-10");

builder.AddAttribute(3, nameof(MudText.ChildContent), (RenderFragment) ((builder2) =>
{
builder2.OpenComponent<MudIcon>(4);
builder2.AddAttribute(5, nameof(MudIcon.Class), "mr-3 mb-n1");
if (IsCreating)
builder2.AddAttribute(6, nameof(MudIcon.Icon), Icons.Material.Filled.Add);
else
builder2.AddAttribute(6, nameof(MudIcon.Icon), Icons.Material.Filled.Edit);
builder2.CloseComponent();
if(IsCreating)
builder2.AddContent(7, $"Create {ObjectName}");
else
builder2.AddContent(7, $"Edit {ObjectName}");
}));
builder.CloseComponent();
};
This works, and in my derived razor components I can invoke TitleFragment() and get the title that I desire. However, I wasn't sure if there was a way to create a RenderFragment in such a way without using the RenderTreeBuilder? Can I instead somehow declare this as razor syntax somewhere within my base razor component, or is this my only option?
7 Replies
Anu6is
Anu6is•4mo ago
can't you just make a component that you'd reuse?
Pingu
Pingu•4mo ago
i could, thats another option... But I was wondering if there was a way to build up a render fragment within a component without doing so using the Builder approach
Anu6is
Anu6is•4mo ago
not that i'm aware
Jimmacle
Jimmacle•4mo ago
if you do it in the .razor file you can use razor markup inside the method
Pingu
Pingu•4mo ago
How would I do that? (confused how that would look sorry)
Jimmacle
Jimmacle•4mo ago
example from one of mine
@code
{
private RenderFragment SortHeader(ListProjects.Sort sort, SortDirection initialDirection = SortDirection.None)
{
return
@<MudTh Style="white-space: nowrap;">
<MudTableSortLabel
T="ListProjects.Response.Item"
SortLabel="@sort.ToString("G")"
InitialDirection="@initialDirection">
@sort.Humanize(LetterCasing.Title)
</MudTableSortLabel>
</MudTh>;
}
}
@code
{
private RenderFragment SortHeader(ListProjects.Sort sort, SortDirection initialDirection = SortDirection.None)
{
return
@<MudTh Style="white-space: nowrap;">
<MudTableSortLabel
T="ListProjects.Response.Item"
SortLabel="@sort.ToString("G")"
InitialDirection="@initialDirection">
@sort.Humanize(LetterCasing.Title)
</MudTableSortLabel>
</MudTh>;
}
}
Pingu
Pingu•4mo ago
ah ok makes sense. Didn't realise that worked like that... Interesting. 🙂 Thanks 🙂