2

次のように Enum を SelectList に変換する Html ヘルパーがあります。

public static HtmlString EnumSelectListFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> forExpression,
    object htmlAttributes,
    bool blankFirstLine) where TModel : class where TProperty : struct
{
    //MS, it its infinite wisdom, does not allow enums as a generic constraint, so we have to check here.
    if (!typeof(TProperty).IsEnum) throw new ArgumentException("This helper method requires the specified model property to be an enum type.");

    //initialize values
    var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
    var propertyName = metaData.PropertyName;
    var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();

    //build the select tag
    var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
    if (htmlAttributes != null)
    {
        foreach (var kvp in htmlAttributes.GetType().GetProperties()
            .ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
        {
            returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
                HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
        }
    }
    returnText += ">\n";

    if (blankFirstLine)
    {
        returnText += "<option value=\"\"></option>";
    }

    //build the options tags
    foreach (var enumName in Enum.GetNames(typeof(TProperty)))
    {
        var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
        var displayValue = enumName;
        var titleValue = string.Empty;
        returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
            HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
        if (enumName == propertyValue)
        {
            returnText += " selected=\"selected\"";
        }
        returnText += string.Format(">{0}</option>\n", HttpUtility.HtmlEncode(displayValue));
    }

    //close the select tag
    returnText += "</select>";
    return new HtmlString(returnText);
}

私が抱えている問題は、列挙型の名前にスペースを含めることができないため、次のように、1単語の列挙値以外のものがあれば、醜い選択リストを取得できることです。

public enum EmployeeTypes
{
    FullTime = 1,
    PartTime,
    Vendor,
    Contractor
}

さて、私は「わかりました!これにはDataAnnotationsを使用します!」という素晴らしいアイデアを思いついたので、列挙型を次のようにしました。

public enum EmployeeTypes
{
    [Display(Name = "Full Time")]
    FullTime = 1,
    [Display(Name = "Part Time")]
    PartTime,
    [Display(Name = "Vendor")]
    Vendor,
    [Display(Name = "Contractor")]
    Contractor
}

...しかし、ヘルパー クラスでこれらの属性にアクセスする方法について頭を悩ませています。誰かが私にこれをさせてもらえますか?

4

2 に答える 2

4

DisplayAttributeループ内でリフレクションを使用して enum フィールドからを読み取ることができます。

foreach (var enumName in Enum.GetNames(typeof(TProperty)))
{
    var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
    var displayValue = enumName;

    // get the corresponding enum field using reflection
    var field = typeof(TProperty).GetField(enumName);
    var display = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
    if (display != null)
    {
        // The enum field is decorated with the DisplayAttribute =>
        // use its value
        displayValue = display.Name;
    }

    var titleValue = string.Empty;
    returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
        HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
    if (enumName == propertyValue)
    {
        returnText += " selected=\"selected\"";
    }
    returnText += string.Format(">{0}</option>\n", HttpUtility.HtmlEncode(displayValue));
}
于 2012-06-25T19:22:33.813 に答える
0

私はいつも、 Enum クラスの拡張メソッドを作成して Description 属性を読み取り、任意の列挙型で ToDescription() を呼び出すことを好んでいました。このようなもの。

public static class EnumExtensions
{
    public static String ToDescription(this Enum value)
    {
        FieldInfo field = value.GetType().GetField(value.ToString());
        DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
        return attribute == null ? value.ToString() : attribute.Description;
    }   
}
于 2013-03-24T14:47:53.437 に答える