3

我需要一些帮助。我正在尝试构建一个需要枚举类型单选按钮组的视图。我有几个这样的枚举类型(类):

[DataContract(Namespace = Constants.SomeDataContractNamespace)]
public enum OneEnumDataContract
{
    [Display(Name = "Text_None", Description = "Text_None", ResourceType = typeof(TextResource))]
    [EnumMember]
    None = 0,

    [Display(Name = "Text_Medium", Description = "Text_Medium", ResourceType = typeof(TextResource))]
    [EnumMember]
    Medium = 1,

    [Display(Name = "Text_Very", Description = "Text_Very", ResourceType = typeof(TextResource))]
    [EnumMember]
    Very = 2
}

在我的模型(一个数据合同,使用 WCF)中,我有这个枚举数据合同的属性:

    [DataMember(Order = 23)]
    [Display(Name = "EnumValue", Description = "EnumValue_Description", ResourceType = typeof(TextResource))]
    public OneEnumDataContract EnumClass1 { get; set; }

在我看来,我会尝试制作这样的单选按钮组(使用助手):

@Html.RadioButtonListEnum("EnumList1", Model.EnumClass1)

我的帮手:

public static MvcHtmlString RadioButtonListEnum<TModel>(this HtmlHelper<TModel> helper, string  NameOfList, object RadioOptions)
    {
        StringBuilder sb = new StringBuilder();
        //som other code for pairing with resourcefile...

        foreach(var myOption in enumTexts.AllKeys)
        {
            sb.Append("<p>");
            sb.Append(enumTexts.GetValues(myOption)[0]);
            sb.Append(helper.RadioButton(NameOfList, System.Convert.ToInt16(myOption)));
            sb.Append("</p>");
        }
        return MvcHtmlString.Create(sb.ToString());
    }

这给了我 , 中的第一个枚举值OneEnumDataContract作为None参数RadioOptions。如何将 datacontract 中的所有枚举值放入助手中?

4

2 回答 2

4

这是我最近创建的。如果您在非枚举上尝试它将不起作用,但可以满足我的枚举需求。我从不同的 DropDownList 助手(如 nikeaa 发布)中复制了一些片段。

#region RadioButtonList


public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes = null) where TModel : class
{
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    String field = ExpressionHelper.GetExpressionText(expression);
    String fieldname = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(field);
    var inputName = fieldname;
    TProperty val = GetValue(htmlHelper, expression);

    var divTag = new TagBuilder("div");
    divTag.MergeAttribute("id", inputName);
    divTag.MergeAttribute("class", "radio");
    foreach (var item in Enum.GetValues(val.GetType()))
    {


        DisplayAttribute[] attr = (DisplayAttribute[])item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(DisplayAttribute), true);
        if (attr == null || attr.Length == 0 || attr[0].Name != null)
        {
            string name = attr != null && attr.Length > 0 && !string.IsNullOrWhiteSpace(attr[0].Name) ? attr[0].Name : item.ToString();
            var itemval = item;
            var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem { Text = name, Value = itemval.ToString(), Selected = val.Equals(itemval) }, htmlAttributes);

            divTag.InnerHtml += radioButtonTag;
        }
    }


    return new MvcHtmlString(divTag.ToString());
}




public static string RadioButton(this HtmlHelper htmlHelper, string name, SelectListItem listItem,
                     IDictionary<string, object> htmlAttributes)
{
    var inputIdSb = new StringBuilder();
    inputIdSb.Append(name)
        .Append("_")
        .Append(listItem.Value);

    var sb = new StringBuilder();

    var builder = new TagBuilder("input");
    if (listItem.Selected) builder.MergeAttribute("checked", "checked");
    builder.MergeAttribute("type", "radio");
    builder.MergeAttribute("value", listItem.Value);
    builder.MergeAttribute("id", inputIdSb.ToString());
    builder.MergeAttribute("name", name);
    builder.MergeAttributes(htmlAttributes);
    sb.Append(builder.ToString(TagRenderMode.SelfClosing));
    sb.Append(RadioButtonLabel(inputIdSb.ToString(), listItem.Text, htmlAttributes));
    sb.Append("<br>");

    return sb.ToString();
}

public static string RadioButtonLabel(string inputId, string displayText,
                             IDictionary<string, object> htmlAttributes)
{
    var labelBuilder = new TagBuilder("label");
    labelBuilder.MergeAttribute("for", inputId);
    labelBuilder.MergeAttributes(htmlAttributes);
    labelBuilder.InnerHtml = displayText;

    return labelBuilder.ToString(TagRenderMode.Normal);
}


public static TProperty GetValue<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
    TModel model = htmlHelper.ViewData.Model;
    if (model == null)
    {
        return default(TProperty);
    }
    Func<TModel, TProperty> func = expression.Compile();
    return func(model);
}

#endregion

我这样用

@Html.RadioButtonListFor(m => m.PlayFormat)

您可能需要更多代码来为更复杂的用途设置正确的元素名称。

如果枚举项具有 Display 属性,则显示名称。否则显示枚举项。如果显示名称为空,则该值不会显示为选项。在这个枚举中,不显示“None”,从枚举值显示“Singles”,“Men's Doubles”和所有其他的都有来自 [Display(Name="Men's Doubles")] 的文本

public enum PlayFormat
{
    [Display(Name=null)]
    None = 0,
    Singles = 1,
    [Display(Name = "Men's Doubles")]
    MenDoubles = 2,
    [Display(Name = "Women's Doubles")]
    WomenDoubles = 3,
    [Display(Name = "Mixed Doubles")]
    MixedDoubles = 4,
    [Display(Name = "Men's Group")]
    MenGroup = 5,
    [Display(Name = "Women's Group")]
    WomenGroup = 6,
    [Display(Name = "Mixed Group")]
    MixedGroup = 7
}

页面看起来像这样(除了每个 - 是一个单选按钮)

- Singles
- Men's Doubles
- Women's Doubles
- Mixed Doubles
- Men's Group
- Women's Group
- Mixed Group
于 2012-07-16T18:56:24.073 回答
1

这是我在互联网上找到的一种帮助方法,用于从枚举中创建下拉列表。您应该能够修改此代码以创建单选按钮而不是下拉菜单。

namespace Localicy.HtmlHelpers {
    public static class HtmlHelperExtensions {
        private static Type GetNonNullableModelType(ModelMetadata modelMetadata) {
            Type realModelType = modelMetadata.ModelType;
            Type underlyingType = Nullable.GetUnderlyingType(realModelType);
            if (underlyingType != null)
                realModelType = underlyingType;

            return realModelType;
        }

        private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };

        public static string GetEnumDescription<TEnum>(TEnum value) {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if ((attributes != null) && (attributes.Length > 0))
                return attributes[0].Description;
            else
                return value.ToString();
        }

        public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) {
            return EnumDropDownListFor(htmlHelper, expression, null, null);
        }

        public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string defaultValueText) {
            return EnumDropDownListFor(htmlHelper, expression, defaultValueText, null);
        }

        public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string defaultValueText, object htmlAttributes) {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            Type enumType = GetNonNullableModelType(metadata);
            IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
            IEnumerable<SelectListItem> items = from value in values
                                                select new SelectListItem {
                                                    Text = GetEnumDescription(value),
                                                    Value = value.ToString(),
                                                    Selected = value.Equals(metadata.Model)
                                                };

            // If the enum is nullable, add an 'empty' item to the collection
            if (metadata.IsNullableValueType || defaultValueText != null)
                if(defaultValueText != null) {
                    SelectListItem[] tempItem = new[] { new SelectListItem { Text = defaultValueText, Value = "" } };
                    items = tempItem.Concat(items);
                }
                else
                    items = SingleEmptyItem.Concat(items);
                //items = (new ).Concat(items)

            return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
        }
    }
}
于 2012-07-16T14:52:01.280 回答