How do you correctly wire up dynamically created buttons in Blazor?

.net-standard blazor c# razor

Question

I'm fairly new to web frontend, but thought it would be great to have toggle buttons for every 'flaw' in a matrix I was displaying (so you can choose a path backtracing up the matrix).

Luckily, I figured out how to make buttons dynamically in Blazor... Unfortunately, I can't seem to figure out how to 'wire' the buttons.

If I was statically making a button, I could say onclick="@(()=>alignment.ChangeArrow(1))" for the first flaw location, replace the 1 with a 2 for the second, etc...

Giving it 1 (instead of i) in the below code snippet makes all the buttons work for the 1st flaw, but if I give it the variable i then it doesn't work at all?

@for (int i = 0; i < alignment.FlawList.Count; i++)
{
    <button class="button" style="background-color:@alignment.ReturnColor(i)" onclick="@(()=>alignment.ChangeArrow(i))">@alignment.FlawList[i] @i</button>
}

Is there a better Blazor, web way to do what I am talking about?

Thanks for any guidance.

Accepted Answer

Try this:

@for (int i = 0; i < alignment.FlawList.Count; i++)
{
   var local_i = i;
    <button class="button" style="background-color:@alignment.ReturnColor(local_i)" onclick="@(()=>alignment.ChangeArrow(local_i))">@alignment.FlawList[local_i] @local_i</button>
}

Popular Answer

This may work with adjustments....no idea on performance etc. Seemed like fun to do anyway. Reminds me of doing Winforms, but I really don't like doing long code behind in WinForms. There's something nice about being able to generate RenderFragments in C#.


Place a RenderFragment Tag in the cshtml. (Wherever you need it rendered on the page)

@MyFragment

Create the Change Arrow method

void ChangeArrow(int i)
{
    Console.WriteLine("Changing arrow");
}

Generate the RenderFragment Delegate

static RenderFragment MyFragment = build =>
    {
        for (int i = 0; i < alignment.FlawList.Count; i++)
        {
            build.OpenElement(i + 101, "button"); //Open Element
            build.AddAttribute(i + 101, "style",
                $"background-color:{alignment.ReturnColor(i)}");
            build.AddAttribute(i + 101, "onclick", ChangeArrow(i)); // Assign Func to the onclick Attribute
            build.AddContent(i + 101, $"{alignment.FlawList[i]} {i}");
            build.CloseComponent(); //Making sure to close Element
        }
    };    


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why