2

私はVoteクラスを持っており、それが持つことができるプロパティの1つは投票タイプです。全会一致、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>
4

6 に答える 6

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" },
    ...
};
于 2012-06-26T03:26:59.930 に答える
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

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 コンストラクターを持たず、それ自体の静的な読み取り専用インスタンスを公開する、封印されたクラスで列挙型をエミュレートできます。

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;

これはより柔軟で、文字列の代わりに複合型を使用するか、複数の値を渡すためにフィールドを追加することができます。

しかし...それは実際には列挙型ではありません。

于 2012-06-26T03:43:37.390 に答える
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
}

ここに移動 これはほとんどあなたの解決策 です ドロップダウンリストに列挙値を入力するにはどうすればよいですか?

于 2012-06-26T03:30:06.700 に答える
0

を持っているのでtype、の代わりに両方をラップするdescriptionを作成することをお勧めします。利点は、より多くの作業を減らすことができ、非常に柔軟性があることです。classenum

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,...)
于 2012-06-26T03:37:48.550 に答える
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);

ただし、リフレクションを使用するため、単純さとわずかなパフォーマンス ヒットの間にトレードオフがあります。ほとんどの場合、私はパフォーマンスに影響を与えます...

于 2012-06-26T03:29:55.523 に答える
0

必要に応じて列挙型を使用できますが、列挙型の値と表示したいものとの間のリンクを作成する方法を決定する必要があります。たとえば、「Simple Majority」として表示する SimpleMajority の列挙値です。これを行う 1 つの方法は、こちらで説明されているように、Description 属性とヘルパー クラスを使用することです。

ただし、軽量のコレクション クラスをセットアップして、投票タイプの値とその説明を格納する方が簡単な場合があります。これは、次のように単純な場合もありDictionary<int, string>ます。

于 2012-06-26T03:32:02.083 に答える