在 netcore mvc 6 中使用静态实现的一种方法
public static IHtmlContent RadioButtonSwitchEnumFor<TModel, TProperty>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object selectedValue = null, bool? isHorizontal = true, object htmlAttributes = null)
{
if (htmlHelper == null) throw new ArgumentNullException(nameof(htmlHelper));
if (expression == null) throw new ArgumentNullException(nameof(expression));
var viewData = htmlHelper.ViewData;
var modelExpressionProvider = (ModelExpressionProvider)htmlHelper.ViewContext.HttpContext.RequestServices.GetService(typeof(IModelExpressionProvider));
var modelExplorer = modelExpressionProvider.CreateModelExpression(viewData, expression);
if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {modelExplorer}");
var metaData = modelExplorer.Metadata;
if (!metaData.ModelType.IsEnum)
{
throw new ArgumentException("This helper is intended to be used with enum types");
}
// get the field name
var propertyName = metaData.PropertyName ?? viewData?.ModelMetadata?.Name;
string ctrlName = propertyName?.Replace(".", "");
var names = Enum.GetNames(metaData.ModelType);
var values = Enum.GetValues(metaData.ModelType);
var sb = new StringBuilder();
// Create a radio button for each item in the list
foreach (var name in names)
{
string description = string.Empty;
var propertyValue = names.Where(e => e.StartsWith(name)).Select(e => (int)Enum.Parse(metaData.ModelType, e)).FirstOrDefault();
var memInfo = metaData.ModelType.GetMember(name);
var attributes = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
if (attributes.Length > 0)
{
description = ((DisplayAttribute)attributes[0]).ResourceType != null ? ((DisplayAttribute)attributes[0]).GetName() : name;
}
// Create tag builder
var radio = new TagBuilder("input");
radio.Attributes.Add("id", $"{propertyName}_{name}");
radio.Attributes.Add("name", ctrlName);
radio.Attributes.Add("type", "radio");
radio.Attributes.Add("value", propertyValue.ToString());
string selectedFlag;
if (selectedValue != null)
{
if (propertyValue == Convert.ToInt32(selectedValue))
{
selectedFlag = "class='btn btn-sm btn-success active'";
radio.Attributes.Add("checked", "checked");
}
else
{
selectedFlag = "class='btn btn-sm btn-default'";
}
}
else
{
var selectedPropertyName = modelExplorer.Model;
if (selectedPropertyName != null)
{
if (name == selectedPropertyName.ToString())
{
selectedFlag = "class='btn btn-sm btn-success active'";
radio.Attributes.Add("checked", "checked");
}
else
{
selectedFlag = "class='btn btn-sm btn-default'";
}
}
else
{
if (names.First() == name)
{
selectedFlag = "class='btn btn-sm btn-success active'";
radio.Attributes.Add("checked", "checked");
}
else
{
selectedFlag = "class='btn btn-sm btn-default'";
}
}
}
// Add attributes
radio.MergeAttributes(new RouteValueDictionary(htmlAttributes));
using (var writer = new StringWriter())
{
radio.WriteTo(writer, HtmlEncoder.Default);
sb.AppendFormat("<label {0}>{1}{2}</label>", selectedFlag, writer.ToString(), HttpUtility.HtmlEncode(description));
}
}
var htmlContent = sb.ToString();
var wrapperBuilder = new TagBuilder("div");
wrapperBuilder.MergeAttribute("class", "btn-group btn-toggle radioList");
wrapperBuilder.MergeAttribute("data-toggle", "buttons");
wrapperBuilder.InnerHtml.AppendHtml(htmlContent);
using (var sw = new StringWriter())
{
wrapperBuilder.WriteTo(sw, HtmlEncoder.Default);
return new HtmlString(sw.ToString());
}
}