Search code examples
c#genericsblazormudblazor

How to render a Generic render fragment inside a modal with mudblazor


I have the following situation. I'm developing a reusable modal. I need to send different RenderFragments as the content of the modal.

Here's the modal DetallesEventoModal

@typeparam TItem

<MudDialog>
    <DialogContent>
        @Content
    </DialogContent>
    <DialogActions>
        <MudButton OnClick="CerrarModal" Color="Color.Primary">Cerrar</MudButton>
    </DialogActions>
</MudDialog>

@code {
    [CascadingParameter]
    private MudDialogInstance? MudDialog { get; set; }

    [Parameter, EditorRequired]
    public RenderFragment<TItem>? Content { get; set; } = default!;
    
    private void CerrarModal()
    {
        MudDialog?.Close();
    }
}

As you can see I have a parameter RenderFragment<TItem>? Content The code below shows the button that triggers the modal.

 <MudIconButton Icon="@Icons.Material.Filled.RemoveRedEye"
                OnClick="OnVerAction"></MudIconButton>
@code{
private void OnVerAction()
{
    var options = new DialogOptions
        {
            MaxWidth = MaxWidth.ExtraExtraLarge,
            CloseOnEscapeKey = false,
            DisableBackdropClick = true
        };

    RenderFragment<MyNewFragment> _MyNewFragmentRender = (model) =>@<MyNewFragment SomeProp="hello loremp" />;

    var parameters = new DialogParameters
        {
            ["Content"] = _MyNewFragmentRender
        };

    var dialog = DialogService.Show<DetallesEventoModal<MyNewFragment>>("New Fragment", parameters, options);
}

}

MyNewFragment

@if(SomeProp != null)
{
    <h3>Fragment with @SomeProp loaded!</h3>
} else
{
    <h3>loading...</h3>
}

@code {

    [Parameter]
    public string? SomeProp { get; set; }
}

My issue is that the @content is not rendering the HTML, it is just printing the name of the class. The idea is being able to provide different fragments as content for the modal, so the modal will remain unchanged.


Solution

  • RenderFragment<TItem> means you should be calling @Content(item) where item is of type TItem.

    Remember RenderFragment is a Delegate.

    If you are not passing a context, just use RenderFragment

    public RenderFragment<TItem>? Content { get; set; }

    You do not need the = default! if it is nullable. ?