yToxide
yToxide

Reputation: 730

Blazor component not refresh after event fired

My component contains a Table, I'm calling a func that fire an event when I click on a row like this:

<tr class="@(EqualityComparer<T>.Default.Equals(SelectedItem, rowValue.Key) && HasSelectedItem == true ? "data-grid-body-row-selected" : "data-grid-body-row")" @onclick="@(() => SetSelectedItem(rowValue.Key))">
   @foreach (RowData rowData in rowValue.Value) {
      <td>@rowData.Value</td>
   }
</tr>

public event EventHandler ItemSelected;

private void SetSelectedItem(T item) {
    SelectedItem = item;
    HasSelectedItem = true;
    ItemSelected.Invoke(this, null);
}

The problem is, when I fire ItemSelected event, the class of the <tr> is not updated, however when I remove the line ItemSelected.Invoke(this, null); everything works fine again.

On my parent component I have this:

private MyComponent<Person> _ref;

protected override void OnInitializedAsync() {
   _ref.ItemSelected += ItemSelected;
}

protected virtual void ItemSelected(object sender, EventArgs e) {
   MyComponent<Person> _tmpref = (MyComponent<Person>)sender;
   SelectedPerson = _tmpref.SelectedItem;
   StateHasChanged();
}

and I get the correct Item selected, so I have tried to place StateHasChanged() before and after my Invoke in my component but nothing changed. I can't find what's the problem.

Edit

private async Task SetSelectedItem(T item) {
   SelectedItem = item;
   HasSelectedItem = true;
   await Task.Run(() => ItemSelected.Invoke(this, null));
}

Now it works for few seconds and it get back to the previous state.

Solution

private async Task SetSelectedItem(T item) {
   SelectedItem = item;
   await Task.Run(() => ItemSelected.Invoke(this, null));
   HasSelectedItem = true;
}

I Simply moved my HasSelectedItem = true after the Invoke and now it works but I don't understand why it get back to false if I place it before, while my SelectedItem stay at the good value if I let it before.

Upvotes: 1

Views: 1872

Answers (1)

Attersson
Attersson

Reputation: 4866

SetSelectedItem should be async and ItemSelected awaitable (for example returning a Task). Then the onclick event will correctly wait for the event handler to execute instead to immediately complete without effect, like it does now, because it terminates before the changes have taken effect.

Upvotes: 1

Related Questions