I have created Selectable.razor:
@inherits ComponentBase
<div class="@getClass()" @onclick="() => SetSelected()"></div>
and Selectable.razor.cs:
using Microsoft.AspNetCore.Components;
namespace TestBlazor.Components.Pages
{
public partial class Selectable : ComponentBase
{
public bool selected = false;
public static Selectable? alreadySelected = null;
private string getClass()
{
return selected ? "selectable selected" : "selectable";
}
protected void SetSelected()
{
if (alreadySelected != null)
alreadySelected.selected = false;
selected = true;
alreadySelected = this;
StateHasChanged();
}
}
}
Why is not SetSelected triggered when clicking the div?
GetClass is triggering however (I was setting a breakpoint in there to make sure).
Without the Use case, I'm guessing at the intent of the control.
First, a couple of points:
public static Selectable? alreadySelected = null;
StateHasChanged();
within a UI handler that already calls it on completion.So, based on the code you've provided, this is my refactored version of Selectable
.
Parameters
is private - it's all internal only code.
<div class="@CssClass" style="cursor:pointer" @onclick="SetSelected">
@this.ChildContent
</div>
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public EventCallback<bool> OnChanged { get; set; }
private bool _selected = false;
private string CssClass => _selected ? "bg-success text-white p-2" : "bg-danger text-white p-2";
private async Task SetSelected()
{
_selected = !_selected;
await this.OnChanged.InvokeAsync(_selected);
}
}
And a demo page:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
<Selectable OnChanged="OnSelect">
<h2>Toggle me!</h2>
</Selectable>
@code {
private void OnSelect(bool state)
{
Console.WriteLine($"State:{state}");
}
}