Net MAUI Blazor RenderFragment

Good afternoon!

I'm trying to render the DOM, but it's not working. I can't understand or don't see the error in the code.

After the DIV block with class col-6, the rest of the code is accepted as plain text by the compiler

private RenderFragment userProgram => (__builder) =>
{

    int i = 0;
    string conditionalMarkup = string.Empty;

    foreach (var value in _UserPrograms)
    {

        @if (i == 0)
        {
            conditionalMarkup = "<div class=\"row mt-3\">";
        }

        <div @onclick = '() => runUserProgram("test")' class="col-6"></div>

        if (i == 1)
        {
            conditionalMarkup += "</div>";
            @((MarkupString)conditionalMarkup)
            conditionalMarkup = string.Empty;
        }
        else
        {
            @((MarkupString)conditionalMarkup)
        }

        i++;

        if (i > 1)
        {
            i = 0;
        }
    }

};

I expect to see something like this:

<div class="row mt-3">
   <div class="col-6">Test</div>
   <div class="col-6">Test</div>
</div>
<div class="row mt-3">
   <div class="col-6">Test</div>
   <div class="col-6">Test</div>
</div>
<div class="row mt-3">
   <div class="col-6">Test</div>
   <div class="col-6">Test</div>
</div>

But I get this:

<div class="col-6">Test</div>
<!--!-->
<div class="row mt-3"></div>
<div class="col-6">Test</div>
<!--!-->
<div class="row mt-3"></div>
<div class="col-6">Test</div>
<!--!-->
<div class="row mt-3"></div>
<div class="col-6">Test</div>
<!--!-->
<div class="row mt-3"></div>
<div class="col-6">Test</div>
<!--!-->
<div class="row mt-3"></div>
<div class="col-6">Test</div>

I tried using MarkupString, but using it will not work the event handlers that I need in the future in the DIV block.

Upvotes: 1

Views: 100

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30177

The problem is trying to use unclosed tags within Razor conditional logic. In your case if() {<div>}. Credit to @HenkHolterman [in his deleted answer] for spotting that.

Here's some code I've used in the past that does multi-column lists.

It basically queues the column render fragments, and then writes them out when the row is complete. There's a bit of additional logic to deal with a last partial row. _noOfColumns controls the number of columns.

@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

@Row

@code {
    private int _noOfColumns = 3;
    public record Country(string Name);

    private List<Country> _countries = new()
    {
        new("UK"), new("France"), new("Spain"), new("Portugal"), new("Italy")
    };

    private RenderFragment Row => (__builder) =>
    {
        List<RenderFragment> columns = new();
        foreach (var country in _countries)
        {
            if (columns.Count < _noOfColumns)
            {
                columns.Add(Column(country));
                continue;
            }

            <div class="row mt-3">
                @foreach (var column in columns)
                    @column
            </div>

            columns.Clear();
            columns.Add(Column(country));
        }

        if (columns.Count > 0)
        {
            while(columns.Count < _noOfColumns)
                columns.Add(Column(null));

            <div class="row mt-3">
                @foreach (var column in columns)
                    @column
            </div>
        }
    };

    private RenderFragment<Country?> Column => (Country? value) => (__builder) =>
    {
        <div class="col">
            @((MarkupString)(value?.Name ?? "&nbsp;"))
        </div>
    };
}

enter image description here

Upvotes: 0

Related Questions