Reputation: 65
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?
Upvotes: 4
Views: 13176
Reputation: 345
Blazor cannot get a collection of render fragment as parameters. Here are two different approaches you can pass dynamic components count as a parameter
<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
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
Upvotes: 7
Reputation: 273691
Turn it around: the DatagGridColumnCollection component inserts itself as a CascadingValue and the DatagGridColumn components just call an Add method.
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code
{
public void Add(DataGridColumn colum) { ... }
}
@code {
[CascadingParameter]
private ColumnCollection Parent { get; set; }
protected override void OnInitialized()
{
if (Parent != null) Parent.Add(this);
}
}
Upvotes: 5