I have a component with one child component
<MyBtn Command="@ShowBusyCommand"></MyBtn>
@if(IsBusy)
{
<span>I'm busy</span>
}
@code{
public bool IsBusy { get; set; }
public ICommand ShowBusyCommand => RegisterCommand(() => ShowBusyCommand, CanExecute, ExecuteAsync);
public async Task ExecuteAsync()
{
try
{
IsBusy = true;
await Task.Delay(2000);
}
finally
{
IsBusy = false;
}
}
}
And MyBtn component
<button @onclick="@Execute">Show busy</button>
@code {
[Parameter]
public ICommand Command { get; set; }
public void Execute()
{
Command.Execute(null);
}
}
When I click on the button ExecuteAsync method is executed but the view does not change. I don't see my span with "I'm busy" text.
I've even tried creating an EventCallback in MyBtn
<button @onclick="@OnClickHandler">Show busy</button>
@code {
[Parameter]
public ICommand Command { get; set; }
[Parameter]
public object Receiver { get; set; }
public async Task OnClickHandler()
{
var onClick = EventCallback.Factory.Create(Receiver, () => Command.Execute(null));
await onClick.InvokeAsync(null);
}
}
<MyBtn Command="@ShowBusyCommand" Receiver="this"></MyBtn>
but that did not help either.
I can't figure out why doesn't the parent state change when button in a component is clicked and how can I fix that? Except calling manually StateHasChanged on IsBusy property change.
If I change my parameter from ICommand to EventCallback in MyBtn component and pass ExecuteAsync method it works. Why? How can I make it work by passing ICommand as parameter and invoking Execute method?
EDIT: I just figured out if I remove lambda from EventCallback factory, it works but I don't know why
var onClick = EventCallback.Factory.Create(Receiver, Command.Execute);