Reputation: 458
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.
Upvotes: 4
Views: 2478
Reputation: 14553
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> { }
<LoadingMudButton Loading=_processing OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
<MudText>Click me</MudText>
</LoadingMudButton>
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.
Upvotes: 5
Reputation: 1344
MudButton
already has ChildContent Parameter,
you don't need to inherit it,
Just use it inside your new component, and redefine the parameters you need to pass them to the inner components
Upvotes: 0
Reputation: 30046
MudBlazor's component library inherits from ComponentBase
which isn't really designed for Razor inheritance. You're trying to replace the ChildContent
with your own markup.
You need to lift the markup stuff from the base component, hope there's no privates being used, and copy it into the child markup.
Here's my inherited component:
@inherits MudButton
@using MudBlazor.Extensions
<MudElement @bind-Ref="@_elementReference"
HtmlTag="@HtmlTag"
Class="@Classname"
Style="@Style"
@attributes="UserAttributes"
@onclick="OnClickHandler"
type="@ButtonType.ToDescriptionString()"
href="@Href"
target="@Target"
rel="@(Target=="_blank"?"noopener":null)"
disabled="@Disabled">
<span class="mud-button-label">
@if (!string.IsNullOrWhiteSpace(StartIcon))
{
<span class="@StartIconClass">
<MudIcon Icon="@StartIcon" Size="@Size" Color="@IconColor" />
</span>
}
@if (this.Loading)
{
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true" />
<MudText Class="ms-2">Processing</MudText>
}
else
{
<MudText>@ChildContent</MudText>
}
@if (!string.IsNullOrWhiteSpace(@EndIcon))
{
<span class="@EndIconClass">
<MudIcon Icon="@EndIcon" Size="@Size" Color="@IconColor" />
</span>
}
</span>
</MudElement>
@code {
[Parameter] public bool Loading { get; set; }
}
The code comes from the MubBlazor Github repo here - https://github.com/MudBlazor/MudBlazor/blob/dev/src/MudBlazor/Components/Button/MudButton.razor.
My Demo Page:
@page "/"
<PageTitle>Index</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor!</MudText>
<MudAlert Severity="Severity.Normal">You can find documentation and examples on our website here: <MudLink Href="https://mudblazor.com" Typo="Typo.body2" Color="Color.Inherit"><b>www.mudblazor.com</b></MudLink></MudAlert>
<MudText class="mt-6">
<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>
<MyButton Loading=_processing Disabled="@_processing" OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
Hello
</MyButton>
</MudText>
@code {
private bool _processing;
private async Task ProcessSomething()
{
_processing = true;
await Task.Delay(5000);
_processing = false;
}
}
Upvotes: 0