简体   繁体   中英

Blazor Pass EventCallback as Class Property To Component

I am trying to develop a component in Blazor and I would like it to get all its functionality (texts, EventCallbacks, etc) from a C# class. Something like this:

Blazor Component (Code Behind):

public partial class Card : ComponentBase
{
    [Parameter] public CardData CardData { get; set; }

    protected async Task OnActionFiredEvent(EventCallback<object> eventCallback, object itemId)
    {
        if (eventCallback.HasDelegate)
            await CardData.CardTitleOnClickAction.InvokeAsync(itemId);
    }
}

Blazor Component (Razor):

<!-- Card image -->
<div class="view view-cascade overlay">
    <a>
        <div class="mask rgba-white-slight waves-effect waves-light"></div>
    </a>
</div>

<!-- Card content -->
<div class="card-body card-body-cascade text-center">

    <!-- Title -->
    <h4 class="card-title">
        <a class="waves-effect waves-light" @onclick="@(() => OnActionFiredEvent(CardData.CardTitleOnClickAction, CardData.CardItemId))">
            <strong>@CardData.CardTitle</strong>
        </a>
    </h4>
    <!-- Subtitle -->
    @if (!string.IsNullOrEmpty(CardData.CardSubTitle))
    {
        <h6 class="font-weight-bold indigo-text py-2">@CardData.CardSubTitle</h6>
    }

    <!-- Text -->
    @if (!string.IsNullOrEmpty(CardData.CardText))
    {
        <p class="card-text">
            @CardData.CardText
        </p>
    }
</div>

<!-- Card footer -->
<div class="card-footer text-muted text-center">
    @CardData.CardFooter
</div>

CarData class:

public class CardData
{
    public object CardItemId { get; set; }
    public string CardTitle { get; set; }
    public string CardSubTitle { get; set; }
    public string CardText { get; set; }
    public string CardFooter { get; set; }
    public EventCallback<object> CardTitleOnClickAction { get; set; }
}

Use:

<Card CardData="@(new CardData() {
CardTitle = "TextTitle",
CardTitleOnClickAction = EventCallBackMethod,
CardSubTitle = "TextSubTitle",
CardText = "Text"})" />

The problem is that I get the following error when passing the EventCallBack as a class property: Cannot convert method group 'EventCallBackMethod' to non-delegate type 'EventCallback'. Did you intend to invoke the method?

The method itself that is failing is something like this:

protected async Task EventCallBackMethod()
    {
        await DoSomething();
    }

Any idea how to solve this?

As mentioned by Brian Parker you need to have a type in your callback. If you don't want to pass a value you can pass null , for example;

MyComponent.razor

<button @onclick="OnButtonClicked">Click me</button>

@code{
    [Parameter]
    public EventCallback ButtonClicked{ get; set; }


    protected async Task OnButtonClicked()
    {
        await ButtonClicked.InvokeAsync(null);
    }
}

For example as a razor component, the button click triggers OnButtonClicked , which then invokes ButtonClicked parameter, which can be referenced in a parent page.

Page.razor

@page "/pagename"

<MyComponent ButtonClicked="@ButtonClickedHandler" />

@code{
    protected void ButtonClickedHandler()
    {
        Logger.LogInfo("Button click was handled on the page");
    }
}

If you want to pass parameters you can do so like follows;

MyNextComponent.razor

<button @onclick="OnButtonClicked">Click me</button>

@code{
    [Parameter]
    public EventCallback<bool> ButtonClicked{ get; set; }

    protected async Task OnButtonClicked(bool value)
    {
        await ButtonClicked.InvokeAsync(true);
    }
}

Page.razor @page "/pagename"

<MyNextComponent ButtonClicked="@ButtonClickedHandler" />

@code{
    protected void ButtonClickedHandler(bool value)
    {
        Logger.LogInfo($"Button click was handled on the page: {value}");
    }
}

create your EventCallback like this

    private async Task Press1()
    {
        this.message = "F1";
    }

EventCallback evt1 = EventCallback.Factory.Create(this, Press1);

property

public class CardData
{
    public EventCallback<object> CardTitleOnClickAction { get; set; }
    public static EventCallback GetEvent(CardData data)
    {
        return data.CardTitleOnClickAction;
    }
}

compoment

@onclick="() =>Modal.CardData.GetEvent(data).InvokeAsync()"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM