2012-07-16 63 views
3

我需要一些帮助。我试图建立一个视图,我需要枚举类型的单选按钮组。 我有几个枚举类型(类)是这样的:MVC 3 helper for radiobuttonlist枚举

[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 
} 

在我的模型(datacontract,使用WCF)我有这个属性为枚举datacontract:

[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()); 
    } 

这给我第一个enumvalue在OneEnumDataContract,None,作为参数RadioOptions。 如何将datacontract中的所有enumval都转换为helper?

回答

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属性,则会显示名称。否则,将显示枚举项目。如果显示名称为空,则该值不会显示为选项。在此枚举,“无”不显示,“光棍节”是从枚举值,“男子双打”,并显示所有其他的有从[显示(NAME =“男子双打”)文本

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 
+0

谢谢弗雷德,我喜欢你的解决方案,非常整洁:-)我可以实际使用助手的扩展,因为它们。好的建议,也来自Nikeaa。 – Frankie 2012-07-17 13:33:31

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); 
     } 
    } 
}