Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameters to a Blazor component

I need pass a collection (or array) of parameters to my Blazor component. The parameters passing are Blazor components. The collection of parameters must be passed as a nested tag. It is necessary to be able to call the rendering of each passed parameter-component separately.

That is, I want something like this:

<MyComponent>
  <ParameterCollection>
    <MyParameterComponent1>Caption1</MyParameterComponent1>
    <MyParameterComponent2>Caption2</MyParameterComponent2>
    <MyParameterComponent3>Caption3</MyParameterComponent3>
  </ParameterCollection>
</MyComponent>

MyComponent code:

@code{
    [Parameter]
    public RenderFragment[] ParameterCollection {get; set;} //Runtime error
}

That I want to get is apparently implemented here commercial Blazor component (select the VIEW SOURCE tab). The GridColumns parameter is passed a collection of GridColumn components. More precisely, as I think, it is a collection of their corresponding RenderFragments. The question is how is it done?

like image 504
v.a.v Avatar asked Oct 15 '25 22:10

v.a.v


2 Answers

Blazor cannot get a collection of render fragment as parameters. Here are two different approaches you can pass dynamic components count as a parameter

  1. If you want just to pass multiple components but it's ok they to be rendered at the same order as you passing them:
<MyComponent>
    <ParameterCollection>
        <MyParameterComponent1>Caption1</MyParameterComponent1>
        <MyParameterComponent2>Caption2</MyParameterComponent2>
        <MyParameterComponent3>Caption3</MyParameterComponent3>
    </ParameterCollection>
</MyComponent>
@code{
    [Parameter]
    public RenderFragment ParameterCollection {get; set;} 
}

and you can just render them placing @ParameterCollection anywhere in your .razor file.

Here is a working example of this approach: https://blazorrepl.com/repl/QaFEadlQ52kWHVkX13

  1. When you want to have both dynamic components count and you want to have control over where they are placed.

In this approach you are using the component only to pass some metadata - similar to @Henk Holterman suggestion:

<MyComponent>
    <ParameterCollection>
        <MyParameterComponent1>Caption1</MyParameterComponent1>
        <MyParameterComponent2>Caption2</MyParameterComponent2>
        <MyParameterComponent3>Caption3</MyParameterComponent3>
    </ParameterCollection>
</MyComponent>
@code{
    [Parameter]
    public RenderFragment ParameterCollection {get; set;} 
}

in this way, you can just put the @ParameterCollection at the start of your .razor file wrapped in CascadingValue of the Parent component. This will trigger the rendering for all the child components.

In the init of each of the components you will need to trigger populating metadata to the parent:

@code {
    [CascadingParameter]
    private MyComponent Parent { get; set; }
    protected override void OnInitialized()
    {
        if (Parent != null)  Parent.AddChild(this);    
    }
}

After receiving the metadata, you just need to trigger rendering again and use this data in

Here is a working example: https://blazorrepl.com/repl/wuPOOxvd06vFcWFG21

like image 101
Kristian.mariyanov Avatar answered Oct 17 '25 10:10

Kristian.mariyanov


Turn it around: the DatagGridColumnCollection component inserts itself as a CascadingValue and the DatagGridColumn components just call an Add method.

ColumnCollection

<CascadingValue Value="this">
  @ChildContent
</CascadingValue>

@code
{ 
    public void Add(DataGridColumn colum) { ... }
}

DataGridColumn

@code {
  [CascadingParameter]
  private ColumnCollection Parent { get; set; }
  protected override void OnInitialized()
  {
    if (Parent != null)  Parent.Add(this);    
  }
}
like image 22
Henk Holterman Avatar answered Oct 17 '25 11:10

Henk Holterman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!