2012-07-16 102 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); 
     } 
    } 
}