在 Blazor 中使用 Input radio 并允许可为 null 的 Enum
Using Input radio inside Blazor and allowing nullable Enum
我在 Blazor WebAssembly 项目上工作,我需要显示基于 Enum 的输入单选按钮。
下面是我的'InputRadio.razor'
@using System.Globalization
@typeparam TValue
@inherits InputBase<TValue>
<input @attributes="AdditionalAttributes" type="radio" value="@SelectedValue" checked="@(SelectedValue.Equals(Value))" @onchange="OnChange" />
@code {
[Parameter]
public TValue SelectedValue { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> SelectedValueChanged { get; set; }
private void OnChange(ChangeEventArgs args)
{
if (args.Value is "on") { // <------- only way to test if value is null. Why "on" ???
CurrentValueAsString = null;
} else {
CurrentValueAsString = args.Value.ToString();
}
SelectedValueChanged.InvokeAsync(args);
}
protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = $"{FieldIdentifier.FieldName} field isn't valid.";
return false;
}
}
}
下面是我的'Test.razor'
<EditForm Model="CurrentFilterModel">
<InputRadio name="difficulty" SelectedValue="null" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> All
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Beginner" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Beginner
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Intermediate" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Intermediate
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Advanced" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Advanced
</EditForm>
低于'Test.cs'
public enum EnumDifficulty
{
Beginner,
Intermediate,
Advanced
}
public FilterModel CurrentFilterModel = new FilterModel();
public class FilterModel
{
public EnumDifficulty? DifficultyFilter { get; set; }
...
}
如您所见,使用的 DifficultyFilter
过滤器可以为空。当 null 我知道这个过滤器没有设置。
这个实现有效。每次选择单选按钮时,都会触发 onchange
事件。我很难处理 null
值。在搜索和尝试之后,我发现测试 if (args.Value is "on") ...
允许我管理 null
值。但是为什么 "on" 呢?我没有线索。请看看我上面的代码。
有些人可能会建议我这样调整 Enum
:
public enum EnumDifficulty
{
Any, // <--- added
Beginner,
Intermediate,
Advanced
}
但我不想这样,因为这个枚举也用在我的 Entity Framework 模型上,这不是一个有效的选择。
** 更新 **
下面是 TryParseValueFromString
的完整代码
protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
{
if (typeof(TValue) == typeof(string))
{
result = (TValue)(object)value;
errorMessage = null;
return true;
}
else if (typeof(TValue).IsNullableEnum()) // (typeof(TValue).IsEnum)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
return false;
}
}
if (typeof(TValue) == typeof(int))
{
if (int.TryParse(value, out var resultInt))
{
result = (TValue)(object)resultInt;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = "The chosen value is not a valid number.";
return false;
}
}
throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(TValue)}'.");
}
public static class CustomStaticFunctions
{
public static bool IsNullableEnum(this Type t)
{
Type u = Nullable.GetUnderlyingType(t);
return (u != null) && u.IsEnum;
}
}
不确定你的问题是什么!?你想知道什么 ?什么是 "on?"
"on"是选中单选框的value属性时赋给单选组的值
单选按钮丢失。这是我以前的认识。我的新知识(希望我是对的)来自你,这意味着 value 属性不一定会丢失以导致值 "on" ... value 属性为空(可能为空或为空)就足够了string) 给我们值 "on".
您确定您的组件正常工作吗?您的代码缺少检查枚举值的这一部分:
else if (typeof(TValue).IsEnum)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
return false;
}
}
我在 Blazor WebAssembly 项目上工作,我需要显示基于 Enum 的输入单选按钮。
下面是我的'InputRadio.razor'
@using System.Globalization
@typeparam TValue
@inherits InputBase<TValue>
<input @attributes="AdditionalAttributes" type="radio" value="@SelectedValue" checked="@(SelectedValue.Equals(Value))" @onchange="OnChange" />
@code {
[Parameter]
public TValue SelectedValue { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> SelectedValueChanged { get; set; }
private void OnChange(ChangeEventArgs args)
{
if (args.Value is "on") { // <------- only way to test if value is null. Why "on" ???
CurrentValueAsString = null;
} else {
CurrentValueAsString = args.Value.ToString();
}
SelectedValueChanged.InvokeAsync(args);
}
protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = $"{FieldIdentifier.FieldName} field isn't valid.";
return false;
}
}
}
下面是我的'Test.razor'
<EditForm Model="CurrentFilterModel">
<InputRadio name="difficulty" SelectedValue="null" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> All
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Beginner" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Beginner
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Intermediate" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Intermediate
<InputRadio name="difficulty" SelectedValue="EnumDifficulty.Advanced" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /> Advanced
</EditForm>
低于'Test.cs'
public enum EnumDifficulty
{
Beginner,
Intermediate,
Advanced
}
public FilterModel CurrentFilterModel = new FilterModel();
public class FilterModel
{
public EnumDifficulty? DifficultyFilter { get; set; }
...
}
如您所见,使用的 DifficultyFilter
过滤器可以为空。当 null 我知道这个过滤器没有设置。
这个实现有效。每次选择单选按钮时,都会触发 onchange
事件。我很难处理 null
值。在搜索和尝试之后,我发现测试 if (args.Value is "on") ...
允许我管理 null
值。但是为什么 "on" 呢?我没有线索。请看看我上面的代码。
有些人可能会建议我这样调整 Enum
:
public enum EnumDifficulty
{
Any, // <--- added
Beginner,
Intermediate,
Advanced
}
但我不想这样,因为这个枚举也用在我的 Entity Framework 模型上,这不是一个有效的选择。
** 更新 **
下面是 TryParseValueFromString
的完整代码protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
{
if (typeof(TValue) == typeof(string))
{
result = (TValue)(object)value;
errorMessage = null;
return true;
}
else if (typeof(TValue).IsNullableEnum()) // (typeof(TValue).IsEnum)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
return false;
}
}
if (typeof(TValue) == typeof(int))
{
if (int.TryParse(value, out var resultInt))
{
result = (TValue)(object)resultInt;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = "The chosen value is not a valid number.";
return false;
}
}
throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(TValue)}'.");
}
public static class CustomStaticFunctions
{
public static bool IsNullableEnum(this Type t)
{
Type u = Nullable.GetUnderlyingType(t);
return (u != null) && u.IsEnum;
}
}
不确定你的问题是什么!?你想知道什么 ?什么是 "on?"
"on"是选中单选框的value属性时赋给单选组的值 单选按钮丢失。这是我以前的认识。我的新知识(希望我是对的)来自你,这意味着 value 属性不一定会丢失以导致值 "on" ... value 属性为空(可能为空或为空)就足够了string) 给我们值 "on".
您确定您的组件正常工作吗?您的代码缺少检查枚举值的这一部分:
else if (typeof(TValue).IsEnum)
{
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
return false;
}
}