I'm trying to use 2-way binding between a form and my object. I can get it to work for InputText
. But i get this errors when i add the ValueChanged
attribute for InputNumber
:
CS1662 Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
CS1503 Argument 2: cannot convert from 'method group' to 'EventCallback'
When i compile this Component.razor
page:
@page "/test"
@using System.ComponentModel.DataAnnotations
<EditForm Model="@model">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText Value="@model.Street" ValueExpression="@(() => model.Street)" ValueChanged="@StreetChanged" />
<InputNumber Value="@model.HouseNr" ValueExpression="@(() => model.HouseNr)" ValueChanged="@HouseNrChanged" />
<button type="submit">Send</button>
</EditForm>
@code {
protected void StreetChanged(string? value)
{
// ... code to lookup address and fill other fields
model.Street = value;
}
protected void HouseNrChanged(int? value)
{
// ... code to lookup address and fill other fields
model.HouseNr = value;
}
private Address model { get; set; } = new();
class Address
{
[Required]
public string? Street { get; set; }
[Required]
public int? HouseNr { get; set; }
}
}
I've tried to changing my HouseNrChanged
method, but i can't figure it out. It seems to have something to do with the different types of the ValueChanged
properties:
- InputText.ValueChanged has type
EventCallback<string>
- InputText.ValueChanged has type
EventCallback<TValue>
Questions:
- Any ideas on how to fix this?
- Is there any documentation?
- What does ValueExpression do besides causing a runtime error when it is omitted?
It's very hard to find examples
CodePudding user response:
It's because the type of the generic EventCallback<TValue>
cannot be inferred. You have to set the TValue
property on the InputNumber
<InputNumber TValue="int?" Value="@model.HouseNr" ValueExpression="@(() => model.HouseNr)" ValueChanged="@HouseNrChanged" />
CodePudding user response:
CS1503 Argument 2: cannot convert from 'method group' to 'EventCallback'
This is rather a generic error message which does not pinpoint the issue at hand. See this example this example
The following error message is where the issue is explained:
CS1662 Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
To solve this issue you can either add the TValue attribute (TValue="int?") as suggested by Dimitris Maragkos, or still better, to my mind, as it makes the code clearer and more readable, use a lambda expression like this:
ValueChanged="(int? args) => HouseNrChanged(args)"
Now you can remember the role of the Value and ValueChanged attribute. They actually create a two-way data binding between the a model's property and an input type="" (in your case number
) that is a constituent part of a component. This is how a two-way data binding is created between a variable and an input type="number"
<input type="number" value="@number" @onchange="(args) =>
SelectYourNumber(args)" />
@code
{
private int number = 10;
protected void SelectYourNumber(ChangeEventArgs args)
{
var number = Convert.ToInt32(args.Value);
}
}
Note that the value
attribute's value in value="@number"
must be preceded by the @
sign, while the Value
attribute's value in
Value="@model.HouseNr"
is rather optional, just for backwards compatibility. I'll never use Value="@model.HouseNr"
, but Value="model.HouseNr"
Do you understand the difference ?
The best method to learn how things work is to consult the source code.