Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor - What is the correct way to extend another component?

I'm using MudBlazor component library. In order to show loading on form buttons, the documentation guides like this:

<MudButton Disabled="@_processing" OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
    @if (_processing)
    {
        <MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true"/>
        <MudText Class="ms-2">Processing</MudText>
    }
    else
    {
        <MudText>Click me</MudText>
    }
</MudButton>

Now since I'm doing this a lot, I wanted to wrap this logic inside another component.

The following component does not do the job:

@inherits MudButton

@code {
    bool _loading;

    [Parameter]
    public bool Loading 
    {
        get => _loading;
        set
        {
            _loading = value;
            Disabled = value;
        }
    }

    [Parameter]
    public new RenderFragment ChildContent 
    {
        get => base.ChildContent;
        set => base.ChildContent = ExtendContent(value);
    }

    private RenderFragment ExtendContent(RenderFragment baseContent) => __builder =>
    {
        if (Loading)
        {
            <MudProgressCircular Class="ms-n2" Size="Size.Small" Indeterminate="true" />
        }
        @baseContent
    };
}

I get this error:

The type '<my_component>' declares more than one parameter matching the name 'childcontent'. Parameter names are case-insensitive and must be unique.

like image 976
Parsa99 Avatar asked Oct 17 '25 05:10

Parsa99


1 Answers

Create a component for the loading content:

ButtonLoadingContent.razor

@using MudBlazor
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true" />
<MudText Class="ms-2">Processing</MudText>

BaseLoadingMudButton.cs

using MudBlazor;

public class BaseLoadingMudButton<TComponent> : MudButton
    where TComponent : ComponentBase
{
    protected override void OnParametersSet()
    {
        Disabled = Loading;

        if (Loading is true)
        {
            ChildContent = builder =>
            {
                builder.OpenComponent<TComponent>(sequence: 1);
                builder.CloseComponent();
            };
        }
        base.OnParametersSet();
    }

    [Parameter]
    public bool Loading { get; set; }
}

LoadingMudButton.cs

public class LoadingMudButton : BaseLoadingMudButton<ButtonLoadingContent> { }

Usage

<LoadingMudButton Loading=_processing OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
    <MudText>Click me</MudText>
</LoadingMudButton>

enter image description here enter image description here

Why does it work? I didn't use .razor files for the inheritance. The base component does not have to use generics I included this to make it more flexible and as an example.

like image 110
Brian Parker Avatar answered Oct 19 '25 12:10

Brian Parker