Reputation: 3677
What is the correct way to bind a checkbox and have an event fire when that checkbox changes? I have tried a couple of different ways all not working exactly as I had hoped. Note the checkbox is in a component.
<input type="checkbox" checked="@IsChecked" @onchange="CheckboxChanged">
@code{
[Parameter]
public bool IsChecked { get; set; } = true;
private void CheckboxChanged()
{
Console.WriteLine($"Checkbox changed {IsChecked}");
}
}
When the page loads it reads the value that is given to IsChecked
, and when the CheckBox is checked the method fires. However, the value for IsChecked
is not updated. Then if the binding value for IsChecked
is changed outside of the component, the method does not fire but the value for IsChecked
is changed (should note that UI is updated correctly).
I figured I needed an actual bind like this:
<input type="checkbox" @bind="IsChecked" @onchange="CheckboxChanged" >
However, this gives an error that onchange
is used two or more
<input type="checkbox" @bind="IsChecked" @onclick="CheckboxChanged" >
When the user clicks the checkbox it does fire the method however, IsChecked
is at the old value (I am assuming the click happens before the bind). Then if the value for IsChecked
is changed outside of the component, once again the method does not fire.
What is the correct way?
Upvotes: 28
Views: 52866
Reputation: 856
Like @hans-kesting mentioned, you can use InputCheckbox
. If you would like to have a custom logic on value changed event you can achieve it with this:
<InputCheckbox ValueChanged="@((e) => CheckboxChanged(e))" ValueExpression="@(() => IsChecked)"/>
Note, that you cannot use @bind-Value
and ValueChanged
together. That's why ValueChanged
and ValueExpression
are required to achieve similar behavior.
Additionally, an example of how one might implement simple CheckboxChanged
.
private void CheckboxChanged(bool e)
{
IsChecked = e;
}
Upvotes: 7
Reputation: 31
<input class="form-check-input" type="checkbox" value="@record.IsChecked" checked="@record.IsChecked" @onchange="@((args) => CheckboxChanged((bool)args.Value))"/>
Upvotes: 3
Reputation: 1040
As of .NET 7 you can use the @bind-value:after
to tap into the change event after it's happened.
<input type="checkbox" @bind-value="@IsChecked" @bind-value:after="CheckboxChanged">
@code{
[Parameter]
public bool IsChecked { get; set; } = true;
private void CheckboxChanged()
{
Console.WriteLine($"Checkbox changed {IsChecked}");
}
}
Upvotes: 30
Reputation: 39283
There exists also an InputCheckbox control:
<InputCheckbox @bind-Value=@boolProperty />
This correctly two-way binds to a property of type bool
(non-nullable). Note the capital V in @bind-Value
.
This control needs to be inside an EditForm control.
Upvotes: 3
Reputation: 30046
There are two issues with your code/component:
[Parameters]
within your code. These are set whenever the component updates.OnChanged
event to update isChecked
, so you can't also use it.Here's commented code that works.
OnInput
event.@page "/"
<input type="checkbox" checked="@isChecked" @oninput="CheckboxChanged">
@code{
[Parameter]
public bool IsChecked { get; set; } = true;
// Internal field holding checkbox state
private bool isChecked;
// updates the internal value whwenever the component is updated
// You may not want that??
protected override void OnParametersSet()
{
isChecked = this.IsChecked;
}
private void CheckboxChanged(ChangeEventArgs e)
{
// get the checkbox state
var value = e.Value;
Console.WriteLine($"Checkbox changed {IsChecked}");
}
}
Upvotes: 34