<Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="Forms Button" CssClass="btn btn-primary">
Your Button component should be defined as follows:
@code
{
[Parameter]
public EventCallback<MouseEventArgs> OnClick {get; set;}
[Parameter]
public string Text {get; set;}
}
The above code define two parameter properties that should be assigned from the Parent component. The parent component is the component in which the Button component is instantiated. Note that you should set the above properties from the parent component as attribute properties... you must not set them outside of the component instantiation. Right now it's a warning, but Steve Anderson has already sad that it is going to be a compiler error soon. This is how you instantiate your component in the parent component:
Parent.razor
<Button OnClick="@((args) => btnForms_Clicked(args))" @ref="formsButton"
Text="_text" CssClass="btn btn-primary">
</Button>
@code
{
private Button formsButton;
// Define a local variable wich is bound to the Text parameter
private string _text = "Click me now...";
public void btnForms_Clicked( MouseEventArgs e)
{
_text = "You're a good clicker.";
}
}
Note: When you click on the Button component a click event should be raised in the Button component, and the button component should propagate this event to the parent component; that is to execute the btnForms_Clicked method on the parent component, Here's how you do that:
Button.razor
<div @onclick="InvokeOnClick">@Text</div>
@code
{
[Parameter]
public EventCallback<MouseEventArgs> OnClick {get; set;}
[Parameter]
public string Text {get; set;}
private async Task InvokeOnClick ()
{
await OnClick.InvokeAsync();
}
}
Note that in order to demonstrate how to raise an event in the Button component, and propagate it to the parent component, I'm using a div element, but you can use a button element, etc.
@onclick is a compiler directive instructing to create an EventCallback 'delegate' whose value is the event handler InvokeOnClick. Now, whenever you click on the div element, the click event is raised, and the event handler InvokeOnClick is called... from this event we execute the EventCallback 'delegate' OnClick; in other words, we call the btnForms_Clicked method defined in the parent component.
So what the @ref directive is good for? You may use the @ref directive to get a reference to a component that contain a method you want to call from its parent component: Suppose you define a child component that serves as a dialog widget, and this component define a Show method, that when is called, display the dialog widget. This is fine and legitimate, but never try to change or set parameter properties outside of the component instantiation.