我有一个投票类,它可以拥有的一个属性是投票类型。如一致,3/4投票,简单多数等等。每种类型都需要有一个与之相关的字符串来描述投票类型(如“简单多数需要51%通过”等)。我需要将我的视图模型中的这些投票类型/描述传递给我的视图,然后我可以使用它制作我的下拉列表。
然后,当提交创建投票的表单时,我只需要将投票类型(没有描述)绑定到投票模型(它是视图模型的一部分)。
我只是在短时间内使用C#,我不太清楚枚举是如何工作的。也许枚举不是解决这个问题的方法。
public class VoteViewModel
{
public VoteViewModel()
{
Vote = new Vote();
}
public Vote Vote { get; set; }
public int EligibleVoters { get; set; }
}
这就是我要放下的地方。
<section class="vote-type">
<select name="">
<option value="">Select Vote Type</option>
</select>
<section class="vote-type-info">
<p class="vote-rules">To pass this vote, at least 51% of Eligible Voters must vote to approve it.</p>
</section>
</section>
答案 0 :(得分:3)
您可以在Enum周围创建一个“常量”字典(或者更确切地说,只读取静态,因为您无法创建常量字典)。
public enum VoteType { Unanimous = 1, SimpleMajority = 2, ... }
public static readonly Dictionary<VoteType, string> VoteDescriptions = new Dictionary<VoteType, string>
{
{ VoteType.Unanimous, "Unanimous description" },
{ VoteType.SimpleMajority, "Simple majority" },
...
};
答案 1 :(得分:3)
请注意我只显示字符串,因为它可以是任何类型。在每种情况下,如果可能的话,我会提到如何扩展它以获得更多值。
您可以使用枚举类型作为字典的键(您希望它是唯一的,因此在某些帮助类中将其设置为静态和只读):
private static readonly Dictionary<MyEnum, string> _dict =
{
//Using dictionary initialization
{MyEnum.MyValue, "The text for MyValue"},
{MyEnum.MyOtherValue, "Some other text"},
{MyEnum.YetAnotherValue, "Something else"}
}
public static readonly Dictionary<MyEnum, string> Dict
{
get
{
return _dict;
}
}
并访问相关值:
string text = Dict[MyEnumEmu.MyValue];
或者用:
string text;
if (Dict.TryGetValue(MyEnumEmu.MyValue, out text))
{
//It has the value
}
else
{
//It doesn't have the value
}
这样您就可以访问与枚举值关联的字符串。然后,您可以公开您的词典,以便您可以阅读相应的值。
您需要一个复杂类型来存储多个值。只需使用您的自定义类型而不是字符串。或者,如果可用,您可以使用Tuples
。
访问Dictionary
可能意味着额外的烦恼,希望它也不会意味着线程问题。
您可以使用Enum.GetName来读取枚举值的名称:
string text = Enum.GetName(MyEnum.MyValue);
//text will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text = Enum.GetName(some);
注意:ToString()
也应该有用。
可悲的是,除了字符串之外,这不会起作用。
它还有一个缺点,就是你不能在那里放任何文字(它必须是一个有效的标识符)。
您必须声明属性类型:
[AttributeUsage(AttributeTargets.Field)]
public class EnumValueAttribute : System.Attribute
{
public readonly string _value;
public string Value
{
get
{
return _value;
}
}
public HelpAttribute(string value) // value is a positional parameter
{
//beware: value can be null...
// ...but we don't want to throw exceptions here
_value = value;
}
}
现在将属性应用于枚举:
public enum MyEnum
{
[EnumValue("The text for MyValue")]
MyValue = 1,
[EnumValue("Some other text")]
MyOtherValue = 2,
[EnumValue("Something else")]
YetAnotherValue = 3
}
最后,您需要阅读该属性:
public static string GetValue(MyEnumenumValue)
{
FieldInfo fiendInfo = typeof(MyEnum).GetField(enumValue.ToString());
if (!ReferenceEquals(fiendInfo, null))
{
object[] attributes = fieldInfo.GetCustomAttributes(typeof(EnumValueAttribute), true);
if (!ReferenceEquals(attributes, null) && attributes.Length > 0)
{
return ((EnumValueAttribute)attributes[0]).Value;
}
}
//Not valid value or it didn't have the attribute
return null;
}
现在你可以打电话给它:
string text = GetValue(MyEnum.MyValue);
//text will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text = GetValue(some);
您可以向属性类添加更多字段,并使用它们传递您可能需要的任何其他值。
但这需要反思,如果您在沙箱中运行,它可能无法使用。此外,它每次都会检索属性,在进程中创建一些短期对象。
您可以使用没有公共构造函数的密封类来模拟枚举,并公开其自身的静态只读实例:
public sealed class MyEnumEmu
{
private static readonly string myValue = new MyEnumEmu("The text for MyValue");
private static readonly string myOtherValue = new MyEnumEmu("Some other text");
private static readonly string yetAnotherValue = new MyEnumEmu("Something else");
public static MyEnumEmu MyValue
{
get
{
return myValue;
}
}
public static MyEnumEmu MyOtherValue
{
get
{
return myOtherValue;
}
}
public static MyEnumEmu YetAnotherValue
{
get
{
return yetAnotherValue;
}
}
private string _value;
private MyEnumEmu(string value)
{
//Really, we are in control of the callers of this constructor...
//... but, just for good measure:
if (value == null)
{
throw new ArgumentNullException("value");
}
else
{
_value = value;
}
}
public string Value
{
get
{
return _value;
}
}
}
一如既往地使用它:
var some = MyEnumEmu.MyValue;
并访问相关值:
string text = MyEnumEmu.MyValue.Value;
//text will have the text "MyValue"
//or
string text = some.Value;
这是更灵活的,您可以使用复杂类型而不是字符串,也可以添加额外字段以传递多个值。
但是......它实际上不是一个枚举。
答案 2 :(得分:1)
public class Vote()
{
public VoteType VoteSelectType { get; set; }
}
public enum VoteType
{
[Display(Name = "Enter Text Here")]
unanimous = 1,
[Display(Name = "Enter Text Here")]
threequatervote = 2,
[Display(Name = "Enter Text Here")]
simplymajority = 3
}
转到这里这几乎是你的解决方案 How do I populate a dropdownlist with enum values?
答案 3 :(得分:0)
我之前使用过它,非常方便。
http://www.codeproject.com/Articles/13821/Adding-Descriptions-to-your-Enumerations
简而言之,它让你做的是:
public enum MyColors{
[Description("The Color of my skin")]
White,
[Description("Bulls like this color")]
Red,
[Description("The color of slime")]
Green
}
然后通过简单地调用:
来获取描述String desc = GetDescription(MyColor.Green);
它确实使用了反射,因此在简单性和轻微的性能影响之间存在权衡。大部分时间我都会受到性能影响......
答案 4 :(得分:0)
如果需要,可以使用枚举,但需要决定如何在枚举值和要显示的内容之间建立链接。例如,您希望将SimpleMajority的枚举值显示为“简单多数”。一种方法是使用Description属性和一个辅助类,如here所述。
但是,您可能会发现设置轻量级集合类以存储投票类型值及其描述更容易。这可能就像Dictionary<int, string>
一样简单。您可能会发现这是一种更直接的方法。
答案 5 :(得分:0)
由于您拥有type
和description
,我建议您创建一个class
,而不是enum
。优点是你可以减少更多工作,而且非常灵活。
public class VoteType
{
public string Name{ get; set; }
public string Description{ get; set; }
}
现在,您的Vote
课程将引用此VoteType
。
public class Vote
{
...
public VoteType Type{ get; set; }
}
在VoteViewModel
中,您最好有一个包含所有VoteType
的课程。
public class VoteViewModel
{
...
public IEnumerable<SelectListItem> VoteTypes{ get; set; }
}
现在,您可以轻松地将VoteTypes
绑定到下拉列表中。
@model VoteViewModel
@Html.DropDiwnListFor(m => m.VoteTypes,...)