Reputation: 379
Trying to pass an EventHandler to a Blazor component. Error I'm getting: The event AppState.IntegerChanged can only appear on the left hand side of +=
Seems like this should work, is it a blazor limitation or am I doing something wrong?
Getting compiler error in MixedNumber.razor trying to assign event to ValueChanged.
Thanks
MixedNumber.razor
@inject AppState AppState
<CustomInput [email protected]> </CustomInput>
<CustomInput [email protected]> </CustomInput>
<CustomInput [email protected]> </CustomInput>
@code {
[Parameter] public EventHandler<CustomValidationResult> ValueChanged { get; set; }
public void MixedValueChanged()
{
CustomValidationResult result = new() { Integer = 1, Numerator = 10, Denominator = 100 };
AppState.OnMixedChanged(result);
}
public class CustomValidationResult
{
public double Integer { get; set; }
public double Numerator { get; set; }
public double Denominator { get; set; }
}
}
CustomInput.razor
@code {
[Parameter] public EventHandler<double>? ValueChanged { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
ValueChanged += valueChanged;
}
public void valueChanged(object sender, double newValue)
{
//do something
}
}
AppState.cs
public class AppState
{
public static event EventHandler<double>? IntegerChanged;
public static event EventHandler<double>? NumeratorChanged;
public static event EventHandler<double>? DenominatorChanged;
public static void OnMixedChanged(MixedNumber.CustomValidationResult result)
{
IntegerChanged?.Invoke(new object(), result.Integer);
NumeratorChanged?.Invoke(new object(), result.Numerator);
DenominatorChanged?.Invoke(new object(), result.Denominator);
}
}
Upvotes: 4
Views: 2049
Reputation: 273844
is it a blazor limitation
No.
or am I doing something wrong?
Yes.
public static event EventHandler<double>? IntegerChanged;
An event
is a special kind of property, only stricter. It does not even allow read-access, only (un)subscribing with +=
and -=
. It protects abuse of the underlying delegate that is a value type.
You code as-is will compile when you simply remove the event
keyword. But it won't work because you subscribe to a copy of the delegate. And when you think that is confusing: that is why the event
mechanism was invented.
And there is a strong Blazor guideline against setting a [Parameter]
from the inside.
Now for a solution: I don't see a need for an event
here. It's much simpler.
Give CustomInput a Value property and you're done. You can use OnParameterSet() to react to a value change. And since it is an Input, you probably want to include a Callback.
@code {
[Parameter]
public double Value { get; set; } // don't use the set in this file
[Parameter]
public EventCallback<double> ValueChanged { get; set; } // same
... ValueChanged.InvokeAsync(localValue);
}
@inject AppState AppState
<CustomInput @[email protected]> </CustomInput>
// or:
<CustomInput [email protected] ValueChanged=AppState.NumeratorChanged > </CustomInput>
Upvotes: 4
Reputation: 30465
[Parameter] public EventHandler<double>? ValueChanged { get; set; }
defines a delegate pattern Task MethodName(double value)
. Any method that fits this pattern can be assigned to Parameter in the component declaration.
However you are trying to assign an event to it. You are trying to plug two male sockets together. Both are generators of events, not receivers.
As your intent is not clear from the code snippets provided, all I can say is - Time to rethink.
Upvotes: -1