在 HTML.EnumDropDownListFor 中添加自定义值
Add custom value in HTML.EnumDropDownListFor
到目前为止我有这样的事情:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2
}
并且在视图中,如果我使用:
Html.EnumDropDownListFor(x=>x.EnumProperty)
同时拥有:
public MyEnum EnumProperty {get;set;}
在视图模型上,下拉菜单按预期工作(我看到 FirstElement
,附加的值为 element1
)
问题是我想在值中有一个破折号,像这样:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2,
[Display(Name="Third")]
element-dashed = 3
}
它不会工作,因为 element-dashed 不是一个有效的条目。
这也行不通:
[Value("element-dashed")]
[Display(Name="Third")]
elementDashed = 3
你的问题的答案很简单。但它需要一个解释,解释为什么这是答案。
在枚举中没有需要破折号的功能原因。
假设我有一个工作应用程序,其中包含您的枚举:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2
}
假设我更改了枚举器名称:
public enum MyEnum
{
[Display(Name="FirstElement")]
BatmanIsBruceWayne = 1,
[Display(Name="SecondElement")]
SupermanIsClarkKent = 2
}
我假设代码中对枚举的每次使用也进行了相应调整。如果你在VS(F2)中使用重命名方法,那么会自动出现这种情况。
应用程序的工作方式没有任何变化。从功能上讲,枚举的名称并不重要。
public enum CardSuit { Hearts, Spades, Diamonds, Clubs }
public enum CardSuit { TheRedOne, TheBlackOne, TheOtherRedOne, TheOtherBlackOne }
当然,对于开发人员而言,第一个比第二个更具可读性。然而,编译器并不关心枚举名称的含义。它只关心一致地使用适当的值。
这个和变量名的原理是一样的。当然,我们应该注意使开发人员可读的变量名;没有 技术 原因(即应用程序的功能)为什么我们应该使用 int myDescriptiveInteger
而不是 int x
。
我们选择一个描述性的名称只是为了代码维护人员的可读性。
有一个例外:如果您在枚举上调用 .ToString()
,以便获得您正在使用的字段的字符串表示形式。
注意:虽然这在技术上是可行的,并且其他人之前已经做过;我想知道这是否真的是你应该在这里做的。您已经将显式 int 值分配给枚举值。这些 int 值对于 saving/loading 枚举来说要容易得多,而不是尝试使用它的等效字符串。虽然两者在技术上都是可行的,但使用 int 会好得多,因为占用空间更小,而且没有您在此处错误地尝试修复的命名问题。
从你的问题中不清楚你是否属于这种情况。也许它是在您的应用程序的某个地方完成的,也许不是。你不告诉我我就不知道了。
如果没有完成,那么您的问题在功能上无关紧要。除了可读性目的之外,名称无关紧要,而且我非常相信您的开发人员不会因为缺少破折号而突然停止理解代码的意图。
如果完成,那么您实际上已经提供了问题的答案。而不是在枚举上调用 .ToString()
;相反,您必须 使用 [Display(Name="FirstElement")]
的值作为枚举 .
的正确 "string name"
public static string GetName(this myEnum enumValue)
{
return enumValue.GetType()
.GetMember(enumValue.ToString())
.GetCustomAttribute<DisplayAttribute>()
.GetName();
}
然后可以改成下面的代码:
myEnumValue.ToString();
以下代码正确使用了属性的值而不是枚举字段名称:
myEnumValue.GetName();
在这两种情况下,核心答案保持不变:您无需担心枚举字段的具体名称,因为它在功能上无关紧要。
编辑 如果您希望您的枚举值在组合框中的显示方式与保存值时希望的方式不同,请使用第二个属性来区分二。但原则仍然有效:不要以枚举使用的字段名称为基础。
我想再次强调,您应该使用枚举的 整数值 。我看不出您为什么要明确地将 int 值分配给您的枚举然后拒绝使用它们。
到目前为止我有这样的事情:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2
}
并且在视图中,如果我使用:
Html.EnumDropDownListFor(x=>x.EnumProperty)
同时拥有:
public MyEnum EnumProperty {get;set;}
在视图模型上,下拉菜单按预期工作(我看到 FirstElement
,附加的值为 element1
)
问题是我想在值中有一个破折号,像这样:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2,
[Display(Name="Third")]
element-dashed = 3
}
它不会工作,因为 element-dashed 不是一个有效的条目。 这也行不通:
[Value("element-dashed")]
[Display(Name="Third")]
elementDashed = 3
你的问题的答案很简单。但它需要一个解释,解释为什么这是答案。
在枚举中没有需要破折号的功能原因。
假设我有一个工作应用程序,其中包含您的枚举:
public enum MyEnum
{
[Display(Name="FirstElement")]
element1 = 1,
[Display(Name="SecondElement")]
element2 = 2
}
假设我更改了枚举器名称:
public enum MyEnum
{
[Display(Name="FirstElement")]
BatmanIsBruceWayne = 1,
[Display(Name="SecondElement")]
SupermanIsClarkKent = 2
}
我假设代码中对枚举的每次使用也进行了相应调整。如果你在VS(F2)中使用重命名方法,那么会自动出现这种情况。
应用程序的工作方式没有任何变化。从功能上讲,枚举的名称并不重要。
public enum CardSuit { Hearts, Spades, Diamonds, Clubs }
public enum CardSuit { TheRedOne, TheBlackOne, TheOtherRedOne, TheOtherBlackOne }
当然,对于开发人员而言,第一个比第二个更具可读性。然而,编译器并不关心枚举名称的含义。它只关心一致地使用适当的值。
这个和变量名的原理是一样的。当然,我们应该注意使开发人员可读的变量名;没有 技术 原因(即应用程序的功能)为什么我们应该使用 int myDescriptiveInteger
而不是 int x
。
我们选择一个描述性的名称只是为了代码维护人员的可读性。
有一个例外:如果您在枚举上调用 .ToString()
,以便获得您正在使用的字段的字符串表示形式。
注意:虽然这在技术上是可行的,并且其他人之前已经做过;我想知道这是否真的是你应该在这里做的。您已经将显式 int 值分配给枚举值。这些 int 值对于 saving/loading 枚举来说要容易得多,而不是尝试使用它的等效字符串。虽然两者在技术上都是可行的,但使用 int 会好得多,因为占用空间更小,而且没有您在此处错误地尝试修复的命名问题。
从你的问题中不清楚你是否属于这种情况。也许它是在您的应用程序的某个地方完成的,也许不是。你不告诉我我就不知道了。
如果没有完成,那么您的问题在功能上无关紧要。除了可读性目的之外,名称无关紧要,而且我非常相信您的开发人员不会因为缺少破折号而突然停止理解代码的意图。
如果完成,那么您实际上已经提供了问题的答案。而不是在枚举上调用 .ToString()
;相反,您必须 使用 [Display(Name="FirstElement")]
的值作为枚举 .
public static string GetName(this myEnum enumValue)
{
return enumValue.GetType()
.GetMember(enumValue.ToString())
.GetCustomAttribute<DisplayAttribute>()
.GetName();
}
然后可以改成下面的代码:
myEnumValue.ToString();
以下代码正确使用了属性的值而不是枚举字段名称:
myEnumValue.GetName();
在这两种情况下,核心答案保持不变:您无需担心枚举字段的具体名称,因为它在功能上无关紧要。
编辑 如果您希望您的枚举值在组合框中的显示方式与保存值时希望的方式不同,请使用第二个属性来区分二。但原则仍然有效:不要以枚举使用的字段名称为基础。
我想再次强调,您应该使用枚举的 整数值 。我看不出您为什么要明确地将 int 值分配给您的枚举然后拒绝使用它们。