Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ho to get a specific instance of a custom Blazor Component

Tags:

blazor

Coming from asp.net webforms I have always some doubts how to achieve some task in Blazor, not having a unique ID that references controls, or component.

Let say I have a custom component called MyCard (a simple bootstrap card) that exposes a Visible property:

<div class="card mb-3 @display" style="width: 18rem;">
    <div class="card-body">
        @ChildContent
    </div>
</div>


@code {
    string display = "";

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

    private bool _visible = true;
    [Parameter]
    public bool Visible
    {
        get
        {
            return _visible;
        }
        set
        {
            _visible = value;
            display = value ? "" : "d-none";
        }
    }

}

And then I use more than one on a page:

@page "/"

<h1>Hello, world!</h1>

<MyCard Visible="@hidetoggles[0]">First Card</MyCard>

<MyCard Visible="@hidetoggles[1]">Second Card</MyCard>

<MyCard Visible="@hidetoggles[2]">Third Card</MyCard>

<button @onclick="Hide">Hide the 2nd card</button>

@code
{
    bool[] hidetoggles = new bool[] { true, true, true };

    void Hide()
    {
        hidetoggles[1] = false;
    }
}

Is there a more elegant method to set the property of a specific instance (eg. the second) instead what I did?

Could an ID property in MyCard be useful?

like image 675
SandroRiz Avatar asked Dec 22 '19 17:12

SandroRiz


2 Answers

Quoting Capture references to components docs:

Component references provide a way to reference a component instance so that you can issue commands to that instance, such as Show or Reset. To capture a component reference:

  • Add an @ref attribute to the child component.
  • Define a field with the same type as the child component.

For your code:

MyCard.razor:

<div class="card mb-3 @display" style="width: 18rem;">
    <div class="card-body">
        @ChildContent
    </div>
</div>
    
@code {
    string display = "";

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

    public void setVisible(bool visible)
    {
        if(visible)
        {
            display = "";
        }
        else
        {
            display = "d-none";
        }
    }
}

Index.razor:

<MyCard @ref="MyCardControl1">First Card</MyCard>
<button @onclick="Hide">Hide card</button>
@code{

    MyCard MyCardControl1;

    private void Hide()
    {
        MyCardControl1.setVisible(false);
    }
}   

More info at Blazor Binding, Events and Parameters.

like image 198
Michael Washington Avatar answered Nov 15 '22 07:11

Michael Washington


If your requirement is just hide the card when it is clicked then you can do as below.

MyCard.razor

<div style="@Display" @onclick="Hide">
    This is CardNumber-@CardNumber
</div>

@code{
    [Parameter]
    public int CardNumber { get; set; }
    public string Display{ get; set; }

    public void Hide()
    {
        //By using this keyword you can access the clicked instance. ex: this.CardNumber
        Display = "display:none";
    }
}

Index.razor

@for (int i = 0; i < 5; i++)
{
<MyCard CardNumber="i" />
}
like image 24
chindirala sampath kumar Avatar answered Nov 15 '22 07:11

chindirala sampath kumar