blazorblazor-server-side

How can I declare an array for ChildContent RenderFragment


I have wrote 2 components:

Here is how I want to use this components:

<MyTable>
  <MyLine />
  <MyLine />
  <MyLine />
</MyTable>

Here is what I've wrote for MyTable.razor:

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

It works, but I want to count all "MyLine" components.

Here is what I've tried:

   [Parameter]
   public RenderFragment<MyLine> ChildContent { get; set; }

   [Parameter]
   public RenderFragment<List<MyLine>> ChildContent { get; set; }

But it does not work.

Any idea ?

Thanks


Solution

  • Inside MyTable component define a list that will keep track of MyLine children and two methods for adding and removing items from the list. Also cascade MyTable component to the child components.

    MyTable.razor:

    <CascadingValue Value="this" IsFixed>
        @ChildContent 
    </CascadingValue>
    
    @code {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    
        private readonly List<MyLine> _lines = new();
    
        public void AddLine(MyLine line)
        {
            if (!_lines.Contains(line))
            {
                _lines.Add(line);
                StateHasChanged();
            }
        }
    
        public void RemoveLine(MyLine line)
        {
            if (_lines.Contains(line))
            {
                _lines.Remove(line);
                StateHasChanged();
            }
        }
    }
    

    Then inside MyLine component you can use the cascading parameter to get a reference to the parent component. MyLine will pass itself to the parent list when it's initialized and will remove itself from the parent list when it's disposed.

    MyLine.razor:

    @implements IDisposable
    
    ...
    
    @code {
        [CascadingParameter]
        public MyTable MyTable { get; set; }
    
        protected override void OnInitialized()
        {
            MyTable.AddLine(this);
        }
    
        public void Dispose()
        {
            MyTable.RemoveLine(this);
        }
    }
    

    Now inside parent component you can do _lines.Count to get the result you want.

    BlazorFiddle: https://blazorfiddle.com/s/v6uj2o6m

    Also I would like to point to an example in the documentation for cascading values and parameters where it states:

    TabSet component can provide itself as a cascading value that is then picked up by the descendent Tab components.

    https://learn.microsoft.com/en-us/aspnet/core/blazor/components/cascading-values-and-parameters?view=aspnetcore-6.0#pass-data-across-a-component-hierarchy

    Sometimes it is useful to cascade the parent component to its child components and there is nothing wrong in doing it.