I have been trying to work out how if its possible and how to pass a method from the main page into a component in Blazor.
I have a simple razor page, which contains a component with a button. I want to pass the onclick method from the razor page to the button in the component
Note: I do not need this method to return anything void is fine. I just need to be able to call a method from the main page in a button on the component. I only added int here as a guess since it was complaining about T
@page "/test"
@using Testing.Client.Model;
@using System.Threading;
<TestMethodPassing ExternalMethod="@btnClick"></TestMethodPassing>
@code {
public Action<int> btnClick(){ return 1;}
}
public class TestingMethodPassingModel : ComponentBase
{
[Parameter]
protected Action<int> ExternalMethod { get; set; }
}
@inherits TestingMethodPassingModel;
@using testing.Client.Model;
@using System.Threading;
<button class="btn btn-primary" @onclick="@ExternalMethod" autofocus>External button</button>
@code {
}
The above code gives me the following error
Gives me No overload for 'btnClick' matches delegate 'Action'
I tried doing type T as well and that failed as Blazor cant for some reason find the reference for type T
Working example pieced together from the answers. PassingMethodToComponent
You can pass strings, arrays, numbers, and objects as props. But can you pass a function as a prop? While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.
This is because the Click event of btnClick isn't of the type Action<int>
but actually EventCallback<TIn>
. So change you'll need to change a few things around.
change ExternalMethod to
[Parameter]
protected EventCallback<int> ExternalMethod {get; set;}
and change the btnClick to
public void btnClick(int param) { /* code */ }
// and then set the razor to
<TestMethodPassing ExternalMethod="@btnClick"></TestMethodPassing>
// Or do it with a lambda in the razor
<TestMethodPassing ExternalMethod="@((param) => {/* code */ })"></TestMethodPassing>
There is a GitHub issue tracking the new Event Handling and Binding here
Here is an example of passing a method from a parent to a child and the child invoking it. As you don't require a return value I'm just using Action
rather than Action<T>
.
There are many ways you can make this code more compact, but I've gone for a more verbose example to hopefully show what's happening a bit better.
Parent Component:
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<Child ParentMethod="@SayHello" />
@code {
private void SayHello()
{
Console.WriteLine("Hello!");
}
}
Child Component:
<h3>Child</h3>
<button @onclick="@InvokeParentMethod">Click Me!</button>
@code {
[Parameter] public Action ParentMethod { get; set; }
private void InvokeParentMethod()
{
ParentMethod?.Invoke();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With