Home > Net >  Blazor Checkbox two-way binding and change event
Blazor Checkbox two-way binding and change event

Time:02-23

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?

CodePudding user response:

There are two issues with your code/component:

  1. You should not modify [Parameters] within your code. These are set whenever the component updates.
  2. The bind uses the OnChanged event to update isChecked, so you can't also use it.

Here's commented code that works.

  1. Uses an internal field to hold the checkbox state.
  2. Wired up the 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}");
      }
}
  • Related