2015-05-26 11 views
5

ho questo Enum (Notebook.cs):A proposito di Enum e DataAnnotation

public enum Notebook : byte 
{ 
    [Display(Name = "Notebook HP")] 
    NotebookHP, 

    [Display(Name = "Notebook Dell")] 
    NotebookDell 
} 

Anche questa struttura nella mia classe (TIDepartment.cs):

public Notebook Notebook { get; set; } 

E 'perfettamente funzionante, non mi resta che un "problema":

Ho creato un EnumDDLFor e sta mostrando il nome che ho impostato in DisplayAttribute, con spazi, ma l'oggetto non riceve quel nome in DisplayAttribute, riceve il nome Enum (cosa è corretto), quindi il miodomanda è:

C'è un modo per ricevere il nome con spazi che ho configurato in DisplayAttribute?

+0

Come stai usando l'enumerazione per la proprietà Notebook? Il tuo codice è un po 'confuso. –

+0

Ho modificato, puoi guardare ora? – developer033

risposta

3

MVC non fa uso dell'attributo Visualizzazione sul enumerazioni (o qualsiasi quadro io sappia). È necessario creare un costume Enum classe di estensione:

public static class EnumExtensions 
{ 
    public static string GetDisplayAttributeFrom(this Enum enumValue, Type enumType) 
    { 
     string displayName = ""; 
     MemberInfo info = enumType.GetMember(enumValue.ToString()).First(); 

     if (info != null && info.CustomAttributes.Any()) 
     { 
      DisplayAttribute nameAttr = info.GetCustomAttribute<DisplayAttribute>(); 
      displayName = nameAttr != null ? nameAttr.Name : enumValue.ToString(); 
     } 
     else 
     { 
      displayName = enumValue.ToString(); 
     } 
     return displayName; 
    } 
} 

quindi è possibile utilizzare in questo modo:

Notebook n = Notebook.NotebookHP; 
String displayName = n.GetDisplayAttributeFrom(typeof(Notebook)); 

EDIT: Supporto per la localizzazione

questo potrebbe non essere il più efficiente modo, ma DOVREBBE lavoro.

public static class EnumExtensions 
{ 
    public static string GetDisplayAttributeFrom(this Enum enumValue, Type enumType) 
    { 
     string displayName = ""; 
     MemberInfo info = enumType.GetMember(enumValue.ToString()).First(); 

     if (info != null && info.CustomAttributes.Any()) 
     { 
      DisplayAttribute nameAttr = info.GetCustomAttribute<DisplayAttribute>(); 

      if(nameAttr != null) 
      { 
       // Check for localization 
       if(nameAttr.ResourceType != null && nameAttr.Name != null) 
       { 
        // I recommend not newing this up every time for performance 
        // but rather use a global instance or pass one in 
        var manager = new ResourceManager(nameAttr.ResourceType); 
        displayName = manager.GetString(nameAttr.Name) 
       } 
       else if (nameAttr.Name != null) 
       { 
        displayName = nameAttr != null ? nameAttr.Name : enumValue.ToString(); 
       } 
      } 
     } 
     else 
     { 
      displayName = enumValue.ToString(); 
     } 
     return displayName; 
    } 
} 

Sul enum, è necessario specificare il tipo di chiave e di risorse:

[Display(Name = "MyResourceKey", ResourceType = typeof(MyResourceFile)] 
+0

Funziona come un fascino! :) Grazie. – developer033

+1

Non funziona :(// "ResourceType è un 'tipo' ma è usato come una 'variabile' E cos'è ResFileAssembly? – developer033

+0

Ho aggiornato la mia risposta, aggiunto la parola chiave' new' per il gestore risorse e sto usando il tipo di risorsa specificato da 'ResourceType' nell'annotazione dell'enum.Ho provato questo a livello locale e funziona – akousmata

1

Dal momento che siete preoccuparsi visivi avrei usato un approccio configurabile:

public NotebookTypes NotebookType; 

public enum NotebookTypes{ 
    NotebookHP, 
    NotebookDell 
} 

public string NotebookTypeName{ 
    get{ 
     switch(NotebookType){ 
     case NotebookTypes.NotebookHP: 
      return "Notebook HP"; //You may read the language dependent value from xml... 
     case NotebookTypes.NotebookDell: 
      return "Notebook Dell"; //You may read the language dependent value from xml... 
     default: 
      throw new NotImplementedException("'" + typeof(NotebookTypes).Name + "." + NotebookType.ToString() + "' is not implemented correctly."); 
     } 
    } 
} 
+0

Ho capito la tua risposta, ma è l'unico modo? (Se ho 15 enum, lo devo fare per tutti) .. Btw, mi preoccupo per la visualizzazione perché ho alcune enumerazioni del tipo: 'HigherEducationIncomplete', penso che sia orribile, voglio solo mostrare 'Educazione superiore Incomplete '(come configurato in DisplayAttribute), puoi capire ora? – developer033

+0

@ developer033 No certamente no. Ma questo approccio ti consente di configurare le immagini per linguaggi multilpe. –

+0

Funziona con la risposta di @akousmata. Comunque, grazie, +1 per provare. – developer033

2

Ecco un semplificata (e di lavoro) versione di akousmata è localizzata estensione enum:

public static string DisplayName(this Enum enumValue) 
{ 
    var enumType = enumValue.GetType(); 
    var memberInfo = enumType.GetMember(enumValue.ToString()).First(); 

    if (memberInfo == null || !memberInfo.CustomAttributes.Any()) return enumValue.ToString(); 

    var displayAttribute = memberInfo.GetCustomAttribute<DisplayAttribute>(); 

    if (displayAttribute == null) return enumValue.ToString(); 

    if (displayAttribute.ResourceType != null && displayAttribute.Name != null) 
    { 
     var manager = new ResourceManager(displayAttribute.ResourceType); 
     return manager.GetString(displayAttribute.Name); 
    } 

    return displayAttribute.Name ?? enumValue.ToString(); 
} 

Nota: Sposto enumType da un parametro a una variabile locale.

Esempio utilizzo:

public enum IndexGroupBy 
{ 
    [Display(Name = "By Alpha")] 
    ByAlpha, 
    [Display(Name = "By Type")] 
    ByType 
} 

E

@IndexGroupBy.ByAlpha.DisplayName() 

Ecco un editor di modelli che può essere utilizzato con il metodo di estensione di cui sopra:

@model Enum 

@{  
    var listItems = Enum.GetValues(Model.GetType()).OfType<Enum>().Select(e => 
     new SelectListItem 
     { 
      Text = e.DisplayName(), 
      Value = e.ToString(), 
      Selected = e.Equals(Model) 
     }); 
    var prefix = ViewData.TemplateInfo.HtmlFieldPrefix; 
    var index = 0; 
    ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty; 

    foreach (var li in listItems) 
    { 
     var fieldName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", prefix, index++); 
     <div class="editor-radio"> 
      @Html.RadioButton(prefix, li.Value, li.Selected, new {@id = fieldName}) 
      @Html.Label(fieldName, li.Text) 
     </div> 
    } 
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix; 
} 

E qui è un esempio di utilizzo :

@Html.EditorFor(m => m.YourEnumMember, "Enum_RadioButtonList") 
+1

Una buona presa per ottenere il tipo direttamente dall'enumerazione. Approccio molto più pulito – akousmata