CodeBeam.MudBlazor.Extensions
CodeBeam.MudBlazor.Extensions copied to clipboard
Can MudSelect extension support enum types?
I was wondering if there are any plans to add support for enum types in MudSelect? I think this feature is quite useful in actual projects, and having a new component that supports enums would save a lot of time. If this is not currently on the roadmap, I would be happy to provide an example of how this feature could be used. Thank you for your time and consideration.
@using MudBlazor
@using System.ComponentModel
@using System.Reflection;
@typeparam TEnum
@inherits MudSelect<TEnum>
@{
base.BuildRenderTree(__builder);
}
@code {
bool _isFlagsEnum;
private static bool IsNullableEnum => Nullable.GetUnderlyingType(typeof(TEnum))?.IsEnum ?? false;
private static IList<TEnum> EnumValueList() => EnumOrUnderlyingType().GetEnumValues().Cast<TEnum>().ToList();
private static Type EnumOrUnderlyingType() => IsNullableEnum ? Nullable.GetUnderlyingType(typeof(TEnum)) : typeof(TEnum);
protected override void OnInitialized()
{
Dense = true;
TransformOrigin = Origin.TopLeft;
AnchorOrigin = Origin.BottomLeft;
_isFlagsEnum = EnumOrUnderlyingType().GetCustomAttribute<FlagsAttribute>() != null;
MultiSelection = _isFlagsEnum;
base.OnInitialized();
}
public override async Task SetParametersAsync(ParameterView parameters)
{
await base.SetParametersAsync(parameters);
Setup();
setSelectedValues();
}
private void setSelectedValues()
{
if (_isFlagsEnum)
{
var valueEnum = Value as Enum;
var toSelect = EnumValueList().Where(e => valueEnum?.HasFlag((e as Enum)!) == true).ToList();
SelectedValues = toSelect;
}
else if (Value != null)
{
SelectedValues = new[] { Value };
}
}
void Setup()
{
if (ChildContent == null)
{
ChildContent = __builder =>
{
@foreach (TEnum item in EnumValueList())
{
<MudSelectItem T="TEnum" Value="@item">@(GetDescriptionText(item))</MudSelectItem>
}
};
}
}
string GetDescriptionText<T>(T val)
{
if (val is null) return string.Empty;
var attributes = (DescriptionAttribute[])val.GetType().GetField(val!.ToString()!)!.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : val!.ToString()!;
}
private T SetFlag<T>(T flag, bool set)
{
Enum value = Value as Enum;
Type underlyingType = Enum.GetUnderlyingType(EnumOrUnderlyingType());
// note: AsInt mean: math integer vs enum (not the c# int type)
dynamic valueAsInt = Convert.ChangeType(value, underlyingType);
dynamic flagAsInt = Convert.ChangeType(flag, underlyingType);
if (set)
valueAsInt |= flagAsInt;
else
valueAsInt &= ~flagAsInt;
return (T)valueAsInt;
}
}
Hi, you can use enums with ItemCollection like:
<MudSelectExtended ItemCollection="@(Enum.GetValues<EnumType>())" \>
Isn't it fulfill your requirements?
Hi, you can use enums with ItemCollection like:
<MudSelectExtended ItemCollection="@(Enum.GetValues<EnumType>())" \>Isn't it fulfill your requirements?
Thank you for your response and suggestion. Your solution using enums with ItemCollection can work, but in my case, I need to display the items based on their Description and also support nullable values. However, I will try your approach and see if I can modify it to meet my requirements.
Hi, you can use enums with ItemCollection like:
<MudSelectExtended ItemCollection="@(Enum.GetValues<EnumType>())" \>Isn't it fulfill your requirements?Thank you for your response and suggestion. Your solution using enums with ItemCollection can work, but in my case, I need to display the items based on their Description and also support nullable values. However, I will try your approach and see if I can modify it to meet my requirements.
Would you post your solution to use enum's description and nullable values?