I have this Enum (Notebook.cs):
public enum Notebook : byte
{
[Display(Name = "Notebook HP")]
NotebookHP,
[Display(Name = "Notebook Dell")]
NotebookDell
}
Also this property in my class (TIDepartment.cs):
public Notebook Notebook { get; set; }
It's working perfectly, I just have one "problem":
I created an EnumDDLFor and it's showing the name I setted in DisplayAttribute, with spaces, but the object doesn't receive that name in DisplayAttribute, receives the Enum name (what is correct), so my question is:
Is there a way to receive the name with spaces which one I configured in DisplayAttribute?
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.
Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.
An Enum is a named constant whose underlying type is any integral type except Char. If no underlying type is explicitly declared, Int32 is used. Enum derives from ValueType, but is not a value type.
An enumeration is a data type that consists of a set of named values that represent integral constants, known as enumeration constants. An enumeration is also referred to as an enumerated type because you must list (enumerate) each of the values in creating a name for each of them.
MVC doesn't make use of the Display attribute on enums (or any framework I'm aware of). You need to create a custom Enum extension class:
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;
}
}
Then you can use it like this:
Notebook n = Notebook.NotebookHP;
String displayName = n.GetDisplayAttributeFrom(typeof(Notebook));
EDIT: Support for localization
This may not be the most efficient way, but SHOULD work.
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;
}
}
On the enum, the key and resource type must be specified:
[Display(Name = "MyResourceKey", ResourceType = typeof(MyResourceFile)]
Here's a simplified (and working) version of akousmata's localized enum extension:
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();
}
Note: I move enumType
from a parameter to a local variable.
Example usage:
public enum IndexGroupBy
{
[Display(Name = "By Alpha")]
ByAlpha,
[Display(Name = "By Type")]
ByType
}
And
@IndexGroupBy.ByAlpha.DisplayName()
Here is a editor template that can be used with the extension method above:
@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;
}
And here is an example usage:
@Html.EditorFor(m => m.YourEnumMember, "Enum_RadioButtonList")
Since you are worrying about visuals I would use a configurable approach:
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.");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With