I need to be able to run a function after a selection in made in a . The issue is I\'m also binding with @bind and I get a error when I try to use @o
<input @bind="MyProperty" />
@code {
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
myVar = value;
SomeMethod();
}
}
private void SomeMethod()
{
//Do something
}
}
Please check this example. It is using @bind but upon setting the value it triggers @onchange event
<div class="form-group">
<label for="client">Client Name</label>
<select id="client" @bind="CheckSelected" class="form-control">
<option value="selected1">selected1</option>
<option value="selected2">selected2</option>
</select>
</div>
@code { private string selectedItem {get; set;} private string CheckSelected { get { return selectedItem; } set { ChangeEventArgs selectedEventArgs = new ChangeEventArgs(); selectedEventArgs.Value = value; OnChangeSelected(selectedEventArgs); } } private void OnChangeSelected(ChangeEventArgs e) { if (e.Value.ToString() != string.Empty) { selectedItem = e.Value.ToString(); } } }
You can avoid @bind
altogether (if you're using a foreach
):
<select @onchange=@(x => ...)>
@foreach (var option in _options) {
<option value=@option.Id selected=@(SelectedId == option.Id)>@option.Name</option>
}
</select>
---
public int SelectedId { get; set; }
Some sordid details: I was getting some weird behavior when trying to use F# with server-side Blazor. In short, setting the List
of options to the result of an Entity Framework query (mapped to a list of records) wouldn't @bind
properly, but using a dummy list of options that were C# classes and not F# records did work. It wasn't due to it being records though, because if I set the list to the EF query and then immediately set it to a dummy list of records, it still didn't @bind
properly - but it did work if I commented out the EF line.
This seems to be a popular confusion. Firstly you cant use @onchange
since it would internally be used by @bind
. You should be able to access the selected value from the setter of your CustChanged
property. Based on what you are trying to do with your CustChanged
, you may not even need to manually check when this value is updated. For instance, if your intent is to use CustChanged
in your UI directly or indirectly (within Linq or something), the UI would automatically update with CustChanged
value when your <select>
is changed. Hence, for most use cases I don't see the need to check when it was updated.
To use @onchange
, you can bind it to a function something like this:
public void OnUpdated(ChangeEventArgs e)
{
var selected = e.Value;
}
@bind
is essentially equivalent to the having both value
and @onchange
, e.g.:
<input @bind="CurrentValue" />
Is equivalent to:
<input value="@CurrentValue" @onchange="@((ChangeEventArgs e) => CurrentValue = e.Value.ToString())" />
Since you've already defined @onchange
, instead of also adding @bind
, just add value
to prevent the clash:
<select value="@SelectedCustID" @onchange="@CustChanged" class="form-control">
@foreach (KeyGuidPair i in CustList)
{
<option value="@i.Value">@i.Text</option>
}
</select>
Source: https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-3.1
My recommendation is, if possible, use an EditForm wrapper around your form elements. Then you can detect a change of any of the form elements, in one place. This is good for, for example, a bunch of search filters. Any change in any of the filters should trigger another query of the data, etc.
Example of how to trigger event on form changes is here:
blazor editform change events