'In Blazor, how can I dynamically change an HTML tag?
Let's say I have the following markup in my Blazor component:
<div @attributes=Attributes data-myattr="something">
@ChildContent
</div>
I'd like to provide a way for the parent component to determine which tag is going to be used in place of <div>
. Something like:
<@Tag @attributes=Attributes data-myattr="something">
@ChildContent
</@Tag>
With @Tag being a string Parameter. Of course that doesn't work. I'm aware of templates but it doesn't work for me because I want to be in control the structure of the tag, and add extra attributes to it. I just want to give the user a choice of which tag is going to be displayed.
Solution 1:[1]
Instead of having a .razor file create a .cs file.
In the file create your class public class MyComponent: ComponentBase
and then override BuildRenderTree
NOTE: You'll need to add ?
after the Dictionary<string, object
and RenderFragment
in later versions to indicate they are nullable.
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, YourParameter);
builder.CloseElement();
}
If you don't know exactly how to use the RenderTreeBuilder, simply create a temporary razor file and create the markup you want, then look in obj\Debug\netstandard2.1\Razor\
If you want to achieve this in a .razor
file then you can create a component like this following
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
namespace BlazorApp118.Shared
{
public class Dynamic : ComponentBase
{
[Parameter]
public string Tag { get; set; }
[Parameter]
public Dictionary<string, object> AdditionalAttributes { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
if (string.IsNullOrWhiteSpace(Tag))
throw new ArgumentNullException(nameof(Tag));
builder.OpenElement(0, Tag);
if (AdditionalAttributes?.Any() == true)
builder.AddMultipleAttributes(1, AdditionalAttributes);
if (ChildContent != null)
builder.AddContent(2, ChildContent);
builder.CloseElement();
}
}
}
And then use it like this
<Dynamic Tag="a" AdditionalAttributes=@SomeDictionaryOfValues>
Any content you want here
</Dynamic>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |