我花了一点时间才理解dani herreras 推荐的选项,所以我想为其他人提供一些清晰度。我想将所有文本输入都更改为Bootstrap 5.0 悬浮标签。继承自InputBase<string>
给了我们很多可用的东西。 @CssClass
自动处理应用验证类,而@CurrentValue
给出了组件的@bind-Value
。
InputComponent.razor
@using System.Linq.Expressions
@using Microsoft.AspNetCore.Components.Forms
@inherits InputBase<string>
<div class="form-floating mb-3">
<input class="form-control @CssClass" id="@Id" @bind="@CurrentValue">
<label for="@Id">@Label</label>
</div>
<div class="form-control-validation">
<ValidationMessage For="@ValidationFor" />
</div>
@code {
[Parameter, EditorRequired] public Expression<Func<string>> ValidationFor { get; set; } = default!;
[Parameter] public string? Id { get; set; }
[Parameter] public string? Label { get; set; }
protected override bool TryParseValueFromString(string? value, out string result, out string validationErrorMessage)
{
result = value;
validationErrorMessage = null;
return true;
}
}
SomePage.razor
@using System.ComponentModel.DataAnnotations
<EditForm EditContext="@_editContext" OnValidSubmit=@HandleValidSubmit>
<DataAnnotationsValidator/>
<button type="submit" class="btn btn-primary">Submit</button>
<ValidationSummary />
<InputComponent @bind-Value="person.Name" ValidationFor="@(()=>person.Name)" Label="Name" ></InputComponent>
<p>Two way binded value: @person.Name</p>
</EditForm>
@code {
private class ExamplePerson
{
[Required]
public string Name { get; set; }
}
private ExamplePerson person { get; set; } = new ExamplePerson();
private EditContext _editContext;
protected override void OnInitialized()
{
_editContext = new(person);
}
private async void HandleValidSubmit()
{
}
}
此外,我们可以通过进行以下更改,使用Bootstrap 5.0类名进行验证。
protected override void OnInitialized()
{
_editContext = new(person);
_editContext.SetFieldCssClassProvider(new BootstrapValidationClassProvider());
}
public class BootstrapValidationClassProvider : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
{
if (editContext == null)
throw new ArgumentNullException(nameof(editContext));
bool isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
if (editContext.IsModified(fieldIdentifier))
return isValid ? "is-valid" : "is-invalid";
return isValid ? string.Empty : "is-invalid";
}
}
更新:我在回答这个问题时对Blazor还比较新。我们可以使用typeparam
来实现所有类型的双向绑定,而不是继承InputBase<string>
。
@typeparam TItem
@inherits InputBase<TItem>
.
.
.
[Parameter, EditorRequired] public Expression<Func<TItem>> ValidationFor { get; set; } = default!;
protected override bool TryParseValueFromString(string? value, out TItem result, out string validationErrorMessage)
{
result = (TItem)(object)value;
validationErrorMessage = null;
return true;
}
然后我们会像这样调用该组件
<InputComponent TItem="int" @bind-Value="person.Age" ValidationFor="@(()=>person.Age)" Label="Age" ></InputComponent>
InputText
。我认为他是建议继承自InputBase<string>
来制作自己的 HTML<input>
,同时利用所有的绑定、验证和上下文特性。请看这里 https://dev59.com/PFMH5IYBdhLWcg3w2ULi#73734223 - clamchoda