2016-09-06 78 views
10

我有一個公共enum像這樣:枚舉整數串

public enum occupancyTimeline 
{ 
    TwelveMonths, 
    FourteenMonths, 
    SixteenMonths, 
    EighteenMonths 
} 

,我將使用一個DropDown菜單,如下所示:

@Html.DropDownListFor(model => model.occupancyTimeline, 
    new SelectList(Enum.GetValues(typeof(CentralParkLCPreview.Models.occupancyTimeline))), "") 

現在我正在尋找遠有我值如下

12個月,14個月,16個月,18個月而不是TweleveMonths,十四個月,十六個月,十八個月

我該如何做到這一點?

+0

你的意思是顯示在你的下拉菜單中? –

+0

顯示在下拉菜單中,作爲它的值 – user979331

+0

不幸的是,沒有設置枚舉'.ToString()'函數,我相信。 –

回答

0
public enum occupancyTimeline 
{ 
    TwelveMonths=0, 
    FourteenMonths=1, 
    SixteenMonths=2, 
    EighteenMonths=3 
} 
public string[] enumString = { 
    "12 Months", "14 Months", "16 Months", "18 Months"}; 

string selectedEnum = enumString[(int)occupancyTimeLine.TwelveMonths]; 

public enum occupancyTimeline 
{ 
    TwelveMonths, 
    FourteenMonths, 
    SixteenMonths, 
    EighteenMonths 
} 
public string[] enumString = { 
    "12 Months", "14 Months", "16 Months", "18 Months"}; 


string selectedEnum = enumString[DropDownList.SelectedIndex]; 
+0

我會用'Dictionary '替換你的'string []'enumStrings:更容易維護(例如,如果你將枚舉定義移動到另一個文件中) –

3

我自己做了一個擴展方法,我現在在每一個項目中使用:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Web.Mvc; 

namespace App.Extensions 
{ 
    public static class EnumExtensions 
    { 
     public static SelectList ToSelectList(Type enumType) 
     { 
      return new SelectList(ToSelectListItems(enumType)); 
     } 

     public static List<SelectListItem> ToSelectListItems(Type enumType, Func<object, bool> itemSelectedAction = null) 
     { 
      var arr = Enum.GetValues(enumType); 
      return (from object item in arr 
        select new SelectListItem 
        { 
         Text = ((Enum)item).GetDescriptionEx(typeof(MyResources)), 
         Value = ((int)item).ToString(), 
         Selected = itemSelectedAction != null && itemSelectedAction(item) 
        }).ToList(); 
     } 

     public static string GetDescriptionEx(this Enum @this) 
     { 
      return GetDescriptionEx(@this, null); 
     } 

     public static string GetDescriptionEx(this Enum @this, Type resObjectType) 
     { 
      // If no DescriptionAttribute is present, set string with following name 
      // "Enum_<EnumType>_<EnumValue>" to be the default value. 
      // Could also make some code to load value from resource. 

      var defaultResult = $"Enum_{@this.GetType().Name}_{@this}"; 

      var fi = @this.GetType().GetField(@this.ToString()); 
      if (fi == null) 
       return defaultResult; 

      var customAttributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
      if (customAttributes.Length <= 0 || customAttributes.IsNot<DescriptionAttribute[]>()) 
      { 
       if (resObjectType == null) 
        return defaultResult; 

       var res = GetFromResource(defaultResult, resObjectType); 
       return res ?? defaultResult; 
      } 

      var attributes = (DescriptionAttribute[])customAttributes; 
      var result = attributes.Length > 0 ? attributes[0].Description : defaultResult; 
      return result ?? defaultResult; 
     } 

     public static string GetFromResource(string defaultResult, Type resObjectType) 
     { 
      var searchingPropName = defaultResult; 
      var props = resObjectType.GetProperties(); 
      var prop = props.FirstOrDefault(t => t.Name.Equals(searchingPropName, StringComparison.InvariantCultureIgnoreCase)); 
      if (prop == null) 
       return defaultResult; 
      var res = prop.GetValue(resObjectType) as string; 
      return res; 
     } 

     public static bool IsNot<T>(this object @this) 
     { 
      return !(@this is T); 
     } 
    } 
} 

,然後用它像這樣(在視圖中。例如cshtml)(爲了清晰起見,代碼在兩行中被打破;也可以打上鍊接):

// A SelectList without default value selected 
var list1 = EnumExtensions.ToSelectListItems(typeof(occupancyTimeline)); 
@Html.DropDownListFor(model => model.occupancyTimeline, new SelectList(list1), "") 

// A SelectList with default value selected if equals "DesiredValue" 
// Selection is determined by lambda expression as a second parameter to 
// ToSelectListItems method which returns bool. 
var list2 = EnumExtensions.ToSelectListItems(typeof(occupancyTimeline), item => (occupancyTimeline)item == occupancyTimeline.DesiredValue)); 
@Html.DropDownListFor(model => model.occupancyTimeline, new SelectList(list2), "") 

更新

基於菲爾的建議下,我上面的代碼的可能性更新到一些資源讀枚舉的顯示值(如果您有任何)。資源中的項目名稱應採用Enum_<EnumType>_<EnumValue>(例如Enum_occupancyTimeline_TwelveMonths)的格式。通過這種方式,您可以在資源文件中爲您的枚舉值提供文本,而無需使用某些屬性修飾枚舉值。資源類型(MyResource)直接包含在ToSelectItems方法中。您可以將其作爲擴展方法的參數提取。

命名枚舉值的另一種方式是應用Description屬性(這個工作方式沒有使代碼適應我所做的更改)。例如:

public enum occupancyTimeline 
{ 
    [Description("12 Months")] 
    TwelveMonths, 
    [Description("14 Months")] 
    FourteenMonths, 
    [Description("16 Months")] 
    SixteenMonths, 
    [Description("18 Months")] 
    EighteenMonths 
} 
+1

對我來說,它似乎可能是一個很好的答案,但一些重要的信息缺失。如何指定與枚舉值關聯的自定義文本? – Phil1970

+0

更新了我的回答。希望能幫助到你。 – Jure

+0

我得到一個錯誤'var defaultResult = $「Enum _ {@ this.GetType()。Name} _ {@ this}」;' – user979331

1

製作擴展描述枚舉

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Runtime.CompilerServices; 
using System.ComponentModel; 
public static class EnumerationExtensions 
{ 
//This procedure gets the <Description> attribute of an enum constant, if any. 
//Otherwise, it gets the string name of then enum member. 
[Extension()] 
public static string Description(Enum EnumConstant) 
{ 
    Reflection.FieldInfo fi = EnumConstant.GetType().GetField(EnumConstant.ToString()); 
    DescriptionAttribute[] attr = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
    if (attr.Length > 0) { 
     return attr(0).Description; 
    } else { 
     return EnumConstant.ToString(); 
    } 
} 

} 
+2

鑑於問題出在C#中,您應該在C#中響應,或者至少告訴它是VB.NET,並且可以(輕鬆)進行轉換,以便我們知道您知道這一點。 – Phil1970

+1

感謝提醒我,我更新到C#代碼 –

0

除了使用用於描述一個屬性(見其他答案,或使用谷歌),我經常使用RESX文件,其中關鍵是枚舉文本(例如TwelveMonths),並且該值是所需的文本。

然後做一個能夠返回所需文本的函數並且它也很容易翻譯多語言應用程序的值。

我也想添加一些單元測試來確保所有的值都有相關的文本。如果有一些例外(如可能在年底Count值,那麼單元測試將排除那些檢查。

所有的東西是不是真的很難,相當靈活。如果你使用DescriptionAttribute,想多語言支持,無論如何你需要使用資源文件。

通常,我需要一個類來獲取每個enum類型需要顯示的值(顯示名稱)以及每個資源文件一個單元測試文件,儘管我還有一些其他類用於比較某些常用代碼,如比較資源文件中的鍵單元測試的值爲enum(一個超載允許指定異常)。

順便說一下,在這種情況下,enum的值與月數相匹配(例如,TwelveMonths = 12)可能有意義。在這種情況下,您也可以使用string.Format來顯示值,並且在資源中也有例外(如單數)。

1

您可以使用EnumDropDownListFor來實現此目的。這是你想要的一個例子。 (只是不要忘了用EnumDropDownListFor你應該使用ASP MVC 5和Visual Studio 2015):

您的看法:

@using System.Web.Mvc.Html 
@using WebApplication2.Models 
@model WebApplication2.Models.MyClass 

@{ 
    ViewBag.Title = "Index"; 
} 

@Html.EnumDropDownListFor(model => model.occupancyTimeline) 

而且你的模型:

public enum occupancyTimeline 
{ 
    [Display(Name = "12 months")] 
    TwelveMonths, 
    [Display(Name = "14 months")] 
    FourteenMonths, 
    [Display(Name = "16 months")] 
    SixteenMonths, 
    [Display(Name = "18 months")] 
    EighteenMonths 
} 

參考:What's New in ASP.NET MVC 5.1

0

MVC 5.1

@Html.EnumDropDownListFor(model => model.MyEnum) 

MVC 5

@Html.DropDownList("MyType", 
    EnumHelper.GetSelectList(typeof(MyType)) , 
    "Select My Type", 
    new { @class = "form-control" }) 

MVC 4

您可以參考以下鏈接Create a dropdown list from an Enum in Asp.Net MVC

1
public namespace WebApplication16.Controllers{ 

    public enum occupancyTimeline:int { 
     TwelveMonths=12, 
     FourteenMonths=14, 
     SixteenMonths=16, 
     EighteenMonths=18 
    } 

    public static class MyExtensions { 
     public static SelectList ToSelectList(this string enumObj) 
     { 
      var values = from occupancyTimeline e in Enum.GetValues(typeof(occupancyTimeline)) 
         select new { Id = e, Name = string.Format("{0} Months",Convert.ToInt32(e)) }; 
      return new SelectList(values, "Id", "Name", enumObj); 
     } 
    } 

} 

使用

@using WebApplication16.Controllers 
@Html.DropDownListFor(model => model.occupancyTimeline,Model.occupancyTimeline.ToSelectList()); 
+0

我得到一個錯誤...'@ Html.DropDownListFor(model => model.occupancyTimeline,Model.occupancyTimeline.ToSelectList());':'string'does not contain a ToSelectList'的定義並且沒有擴展方法'ToSelectList'接受'string'類型的第一個參數可以找到(你是否缺少using指令或程序集引用?) – user979331

+0

因爲你必須在View中聲明MyExtension命名空間。 – ebattulga

+0

新錯誤':'字符串'不包含'ToSelectList'的定義和最佳擴展方法重載'CentralParkVIPPreview.Models.MyExtensions.ToSelectList(CentralParkVIPPreview.Models.occupancyTimeline)'有一些無效參數' – user979331

4

您可能會檢查這個link

他溶液瞄準天冬氨酸。NET,但通過簡單的修改就可以在MVC使用它像

/// <span class="code-SummaryComment"><summary></span> 
/// Provides a description for an enumerated type. 
/// <span class="code-SummaryComment"></summary></span> 
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, 
AllowMultiple = false)] 
public sealed class EnumDescriptionAttribute : Attribute 
{ 
    private string description; 

    /// <span class="code-SummaryComment"><summary></span> 
    /// Gets the description stored in this attribute. 
    /// <span class="code-SummaryComment"></summary></span> 
    /// <span class="code-SummaryComment"><value>The description stored in the attribute.</value></span> 
    public string Description 
    { 
     get 
     { 
     return this.description; 
     } 
    } 

    /// <span class="code-SummaryComment"><summary></span> 
    /// Initializes a new instance of the 
    /// <span class="code-SummaryComment"><see cref="EnumDescriptionAttribute"/> class.</span> 
    /// <span class="code-SummaryComment"></summary></span> 
    /// <span class="code-SummaryComment"><param name="description">The description to store in this attribute.</span> 
    /// <span class="code-SummaryComment"></param></span> 
    public EnumDescriptionAttribute(string description) 
     : base() 
    { 
     this.description = description; 
    } 
} 

助手,讓你建立鍵和值的列表

/// <span class="code-SummaryComment"><summary></span> 
/// Provides a static utility object of methods and properties to interact 
/// with enumerated types. 
/// <span class="code-SummaryComment"></summary></span> 
public static class EnumHelper 
{ 
    /// <span class="code-SummaryComment"><summary></span> 
    /// Gets the <span class="code-SummaryComment"><see cref="DescriptionAttribute" /> of an <see cref="Enum" /></span> 
    /// type value. 
    /// <span class="code-SummaryComment"></summary></span> 
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Enum" /> type value.</param></span> 
    /// <span class="code-SummaryComment"><returns>A string containing the text of the</span> 
    /// <span class="code-SummaryComment"><see cref="DescriptionAttribute"/>.</returns></span> 
    public static string GetDescription(Enum value) 
    { 
     if (value == null) 
     { 
     throw new ArgumentNullException("value"); 
     } 

     string description = value.ToString(); 
     FieldInfo fieldInfo = value.GetType().GetField(description); 
     EnumDescriptionAttribute[] attributes = 
     (EnumDescriptionAttribute[]) 
     fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false); 

     if (attributes != null && attributes.Length > 0) 
     { 
     description = attributes[0].Description; 
     } 
     return description; 
    } 

    /// <span class="code-SummaryComment"><summary></span> 
    /// Converts the <span class="code-SummaryComment"><see cref="Enum" /> type to an <see cref="IList" /> </span> 
    /// compatible object. 
    /// <span class="code-SummaryComment"></summary></span> 
    /// <span class="code-SummaryComment"><param name="type">The <see cref="Enum"/> type.</param></span> 
    /// <span class="code-SummaryComment"><returns>An <see cref="IList"/> containing the enumerated</span> 
    /// type value and description.<span class="code-SummaryComment"></returns></span> 
    public static IList ToList(Type type) 
    { 
     if (type == null) 
     { 
     throw new ArgumentNullException("type"); 
     } 

     ArrayList list = new ArrayList(); 
     Array enumValues = Enum.GetValues(type); 

     foreach (Enum value in enumValues) 
     { 
     list.Add(new KeyValuePair<Enum, string>(value, GetDescription(value))); 
     } 

     return list; 
    } 
} 

那麼你裝飾你的枚舉作爲

public enum occupancyTimeline 
{ 
    [EnumDescriptionAttribute ("12 months")] 
    TwelveMonths, 
    [EnumDescriptionAttribute ("14 months")] 
    FourteenMonths, 
    [EnumDescriptionAttribute ("16 months")] 
    SixteenMonths, 
    [EnumDescriptionAttribute ("18 months")] 
    EighteenMonths 
} 

您可以在控制器中使用它來填充下拉列表

ViewBag.occupancyTimeline =new SelectList(EnumHelper.ToList(typeof(occupancyTimeline)),"Value","Key"); 

,並在您看來,您可以使用以下

@Html.DropdownList("occupancyTimeline") 

希望它會幫助你

0

發帖模板解決方案,您可以根據您的需要改變某些部分。

定義通用EnumHelper用於在格式化枚舉:

public abstract class EnumHelper<T> where T : struct 
{ 
    static T[] _valuesCache = (T[])Enum.GetValues(typeof(T)); 

    public virtual string GetEnumName() 
    { 
     return GetType().Name; 
    } 

    public static T[] GetValuesS() 
    { 
     return _valuesCache; 
    } 

    public T[] GetValues() 
    { 
     return _valuesCache; 
    }  

    virtual public string EnumToString(T value) 
    { 
     return value.ToString(); 
    }     
} 

定義MVC通用的下拉列表擴展幫助:

public static class SystemExt 
{ 
    public static MvcHtmlString DropDownListT<T>(this HtmlHelper htmlHelper, 
     string name, 
     EnumHelper<T> enumHelper, 
     string value = null, 
     string nonSelected = null, 
     IDictionary<string, object> htmlAttributes = null) 
     where T : struct 
    { 
     List<SelectListItem> items = new List<SelectListItem>(); 

     if (nonSelected != null) 
     { 
      items.Add(new SelectListItem() 
      { 
       Text = nonSelected, 
       Selected = string.IsNullOrEmpty(value), 
      }); 
     } 

     foreach (T item in enumHelper.GetValues()) 
     { 
      if (enumHelper.EnumToIndex(item) >= 0) 
       items.Add(new SelectListItem() 
       { 
        Text = enumHelper.EnumToString(item), 
        Value = item.ToString(),     //enumHelper.Unbox(item).ToString() 
        Selected = value == item.ToString(), 
       }); 
     } 

     return htmlHelper.DropDownList(name, items, htmlAttributes); 
    } 
} 

您需要格式化一些枚舉任何時間定義EnumHelper特定枚舉T:

public class OccupancyTimelineHelper : EnumHelper<OccupancyTimeline> 
{ 
    public override string EnumToString(occupancyTimeline value) 
    { 
     switch (value) 
     { 
      case OccupancyTimelineHelper.TwelveMonths: 
       return "12 Month"; 
      case OccupancyTimelineHelper.FourteenMonths: 
       return "14 Month"; 
      case OccupancyTimelineHelper.SixteenMonths: 
       return "16 Month"; 
      case OccupancyTimelineHelper.EighteenMonths: 
       return "18 Month"; 
      default: 
       return base.EnumToString(value); 
     } 
    } 
} 

最後使用查看代碼:

@Html.DropDownListT("occupancyTimeline", new OccupancyTimelineHelper()) 
0

我會去一個稍微不同的,也許更簡單的方法:

public static List<int> PermittedMonths = new List<int>{12, 14, 16, 18}; 

然後簡單:

foreach(var permittedMonth in PermittedMonths) 
{ 
    MyDropDownList.Items.Add(permittedMonth.ToString(), permittedMonth + " months"); 
} 

在你所描述的方式使用枚舉我覺得可能會有點的陷阱。