Search code examples
c#asp.net-coreblazor.net-8.0

EditContext not cascaded into custom input derived from InputBase<T>


I have implemented my custom TextInput input component by deriving from InputBase<string?> class. After investigations, found out that the EditContext property of my component is not initialized though I've used my component within an EditForm. If I add the official InputText component which is developed by Microsoft, the problem is solved and the official component's EditContext property is initialized.
I compared my own implementation with the one from Microsoft and they are almost the same but in that mine has a .razor part.
Here is the implementation from Microsoft. This is my custom implementation:

custom component definition:

public partial class TextInput : InputBase<string?>
{
    [Parameter] public string WrapperCssClass { get; set; } = "";
    [Parameter] public string InputCssClass { get; set; } = "";
    [Parameter] public string? Label { get; set; }
    [Parameter] public string? Placeholder { get; set; }
    [Parameter] public bool Required { get; set; } = false;
    [Parameter] public bool Disabled { get; set; } = false;
    [DisallowNull] public ElementReference? Element { get; protected set; }

    protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out string result, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        result = value;
        validationErrorMessage = null;
        return true;
    }
}
@inherits InputBase<string?>


<div class="wrapper @WrapperCssClass">
    @if(!string.IsNullOrWhiteSpace(Label))
    {
        <label class="form-label lbl @(Required ? "required": "")">@Label</label>
    }
    <input @ref="Element" @bind="CurrentValueAsString" class="form-control @CssClass" placeholder="@Placeholder" disabled="@Disabled"/>

</div>

And this is how i've used the component:

<EditForm EditContext="DetailsModelEditContext">
    <div class="d-flex flex-column flex-grow-1 row-gap-3">

        // This one's EditContext is null
         <TextInput Label="عنوان بن تخفیف" @bind-Value="CodeModel.StaticCode" />

        // This one's EditContext is initialized
        <InputText @bind-Value="CodeModel.StaticCode"></InputText>

    </div>
</EditForm>

Solution

  • I'm using the BitPlatform. A few source generators are shipped with the boilerplate project of BitPlatform which help with the optimization of the app. Seems that the generated source code for SetParametersAsync method, interferes with capturing the EditContext within InputBase<string? component.
    My work around for that, for now is to prevent the source generation by implementing the SetParametersAsync:

    public override Task SetParametersAsync(ParameterView parameters)
    {
        // without this method, the CascadedEditContext won't be initialized. I suspect this is because Bit generates some source code which corrupts the initialization of CascadedEditContext
        parameters.SetParameterProperties(this);
        return base.SetParametersAsync(parameters);
    }
    

    The issue is tracked here