Home > Software engineering >  How to bind a reference to a component in blazor using the RenderTreeBuilder?
How to bind a reference to a component in blazor using the RenderTreeBuilder?

Time:07-19

I would like to know how I can implement the @ref attribute using the RenderTreeBuilder. Following blazor code is a minimalistic example to discuss about a solution:

<MudForm @ref="_Form">@ChildContent</MudForm>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private MudForm _Form;
}

I would like to reimplement the blazor code referring to the MudForm using the RenderTreeBuilder. Therefore I already tried the following approach but it didn't work for me:

private RenderFragment formControl => (builder) =>
    {
        builder.OpenComponent<MudForm>(0);
        builder.AddElementReferenceCapture(1, (value) => { _Form = value.Context; });
        builder.AddAttribute(2, nameof(MudForm.ChildContent), ChildContent);
        builder.CloseComponent();
    };

I don't know if the AddElementReferenceCapture-method is correct to bind _Form to the components instance using the RenderTreeBuilder. Could someone please help me with this?

CodePudding user response:

I think you need to cast value as it's provided as an object.

See the code below:

builder.AddElementReferenceCapture(1, (value) => { _Form = (MudForm)value; });

For reference:

You can get the Razor Compiler to emit the class files by adding this line to the project file:

  <PropertyGroup>
  .....
      <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  </PropertyGroup>

And then view the files in /obj/Debug/net6.0/generated/....

Here's a simple Razor file:

@page "/"

<h1>Hello, world!</h1>

<MinimumComponent @ref=this.myComponent/>

@code {
    private MinimumComponent myComponent;
}

And the Razor compiler generated code:

    public partial class Test : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.AddMarkupContent(0, "<h1>Hello, world!</h1>\r\n\r\n");
            __builder.OpenComponent<BlazorApp3.Data.MinimumComponent>(1);
            __builder.AddComponentReferenceCapture(2, (__value) => {
#nullable restore
#line 5 "C:\Users\shaun\source\repos\BlazorApp3\BlazorApp3\Pages\Test.razor"
                       this.myComponent = (BlazorApp3.Data.MinimumComponent)__value;

#line default
#line hidden
#nullable disable
            }
            );
            __builder.CloseComponent();
        }
        #pragma warning restore 1998
#nullable restore
#line 7 "C:\Users\shaun\source\repos\BlazorApp3\BlazorApp3\Pages\Test.razor"
       
    private MinimumComponent myComponent;

#line default
#line hidden
#nullable disable
    }
  • Related