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>