blazorblazor-component

Blazor component: change classes based on number of children


I think it should be relatively simple but I could not find how to do it.

I have this:

<div class="row">
    <div class="col-6 col-12-small">
        <p>
            Lorem lipsum.
        </p>
    </div>
    <div class="col-6 col-12-small">
        <span class="image fit">
            <img src="images/test.jpg"/>
        </span>
    </div>
</div>

and I would like to create a component that would help make coding faster and cleaner. I would like something like this:

<MyGrid>
    <MyGridColumn>
        <p>
            Lorem lipsum.
        </p>
    </MyGridColumn>
    <MyGridColumn>
        <span class="image fit">
            <img src="images/test.jpg"/>
        </span>
    </MyGridColumn>
</MyGrid>

The component would change the classes depending on the number of GridColumn. If 2 children: "col-6 col-12-small", if three, "col-4 col-12-small",... and add maybe later more complexity.


Solution

  • Use a registration process with the parent component. This is a basic example the registration process could exchange a lot more information, parameters, sizes etc.

    Parent.razor

    <div>I have @Count children</div>
    <CascadingValue Value="this">
        @ChildContent
    </CascadingValue>
    
    @code {
        private List<ComponentBase> children = new();
    
        [Parameter, EditorRequired]
        public RenderFragment ChildContent { get; set; } = default!;
    
        internal int Count => children.Count;
        internal void Register(ComponentBase componentBase)
        {
            children.Add(componentBase);
            StateHasChanged();
        }
    }
    

    Child.razor

    @ChildContent/@Parent.Count
    @code {
        [CascadingParameter]
        public Parent Parent { get; set; } = default!;
    
        [Parameter, EditorRequired]
        public RenderFragment ChildContent { get; set; } = default!;
    
        protected override void OnInitialized()
        {
            if (Parent is null) throw new SpitTheDummyException();
    
            Parent.Register(this);
        }
    
        public class SpitTheDummyException() :
            Exception("I need a parent! Place the Child within a Parent"); // C# 12
    }
    
    

    Usage

    <Parent>
        <Child>One</Child>
        <Child>Two</Child>
        <Child>Three</Child>
    </Parent>
    

    Output

    enter image description here