Home > Mobile >  Passing reference of component to its ChildContent components
Passing reference of component to its ChildContent components

Time:08-25

To add some context, I'm trying to create a Dropdown select Blazor component. I've managed to create a concept of this entirely with CSS, @onclick, and @onfocusout.

I'm trying to pass a reference of the DropDown component to its children, DropDownItem. The only way I know how to achieve this, is by using the @ref and passing it as a parameter to the DropDownItem component.

<DropDown @ref="DropDownReference">
    <DropDownItem ParentDropDown=@DropDownReference>Hello</DropDownItem>
    <DropDownItem ParentDropDown=@DropDownReference>World</DropDownItem>
</DropDown>

There has to be a cleaner approach here that does not require manually passing the reference down to each child instance. I suppose I could use CascadingValue but that will still require me to store the DropDown reference.

I'm trying to notify DropDown parent when a click event occurs in DropDownItem. This will signal the parent to changes it selected value - as it would traditionally work in a select.

CodePudding user response:

Here is an example of how you could do it using CascadingValue. The DropDownItem component will accept a [CascadingParameter] of type DropDown. There is nothing wrong in doing that, this is how it's done in most (if not all) component libraries.

DropDown.razor

<CascadingValue Value="this" IsFixed="true">
    @* Dropdown code *@
    <div >
        @ChildContent
    </div>
</CascadingValue>

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

    public void SelectItem(string item)
    {
        selectedItem = item;
        StateHasChanged();
    }
}

DropDownItem.razor

@* Dropdown item code *@
<div  @onclick="OnItemClick">...</div>

@code {
    [CascadingParameter] public DropDown ParentDropDown { get; set; }
    [Parameter] public string Name { get; set; }

    private void OnItemClick()
    {
        ParentDropDown.SelectItem(Name);
    }
}

Usage:

<DropDown>
    <DropDownItem Name="Hello">Hello</DropDownItem>
    <DropDownItem Name="World">World</DropDownItem>
</DropDown>
  • Related