3

enumプロパティを使用してドロップダウンリストを作成し、選択した項目を設定できる拡張メソッドを使用しようとしています。

public enum DefaultEnumSelectItemOptions
{
    AddDefaultItemIfEnumIsZero,
    ZeroEnumIsDefaultItem
}
public static SelectList ToSelectList(this object enumObj, DefaultEnumSelectItemOptions option = DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
{
    var asEnum = Enum.Parse(enumObj.GetType(), enumObj.ToString());
    var values = Enum.GetValues(enumObj.GetType());
    var dataItems = new List<Tuple<string, int>>();
    dataItems.Add(new Tuple<string, int>("Select One", -1));
    for (int i = 0; i < values.Length; i++)
    {
        int enumValue = (int)values.GetValue(i);
        if (enumValue == 0)
        {
            if (option != DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
            {
                dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
            }
        }
        else
        {
            dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
        }
    }
    var selectedItemValue = (int)enumObj;
    if (selectedItemValue == 0 && option == DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
    {
        selectedItemValue = -1;
    }
    return new SelectList(dataItems, "Item2", "Item1", selectedItemValue);
}

モデルは次のようになります。

public enum PropertyTypes
{
    Unknown=0,
    Vehicle,
    Other
}

[DataContract]
public class Property : ClaimEntity
{
    [DataMember]
    public PropertyTypes PropertyType { get; set; }

    public Property()
    {
        this.PropertyType = PropertyTypes.Vehicle;
    }
}

最後に、ビューは次のようになります。

@Html.DropDownListFor(m => m.PropertyType, Model.PropertyType.ToSelectList())

拡張メソッドにブレークポイントを設定すると、正しいように見えますが、選択したオプションがhtmlに表示されません。

ドロップダウンの問題

私は何が間違っているのですか?

編集提案どおりに使用するように変更しましたがSelectListItem、値が選択されていません。

ここに画像の説明を入力してください

4

2 に答える 2

7

私自身、まさにこの問題に直面しており、DropDownListFor (および DropDownList) ヘルパーが少し頭が良すぎて、それ自体が役に立たないことを発見しました。

SelectListItemそれらのいずれかでのセットを渡した場合でもSelected = true、ヘルパーは実際にモデルを評価し、Convert.ToString()それに対して a を実行し、値を一致させようとします。値が見つからない場合は、何も選択されません。

個人的には、これは MVC の大きな誤りであり、MVC4 では修正されていないように思われます。ToString()オブジェクトのメソッドがドロップダウンの値 (表示テキストではなく) と一致するというのは、完全に間違った仮定です。

編集:これを修正する方法については...

  1. ToString()値を返すようにメソッドを変更し、表示テキストを取得する別の方法を見つけてください。
  2. 列挙型を使用しているため、値と表示テキストの両方に文字列バージョンのみを使用できます。それはまだうまくバインドします。
  3. 独自のドロップダウンを作成する
于 2012-05-18T15:28:02.173 に答える
0

誰かが興味を持っている場合、ドロップダウンを作成するためにこのアプローチを使用しました。これは機能しますが、MVC を初めて使用するため、賢明な方法ではない可能性があります。その列挙値が有効な列挙型に対応していることを確認し、それを選択リストメソッドのオーバーロードにプッシュする必要がありますが、急いでいるのでそうしません。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

    public static class Extensions
    {
        public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
        {
            var typeOfProperty = modelExpression.ReturnType;
            if (!typeOfProperty.IsEnum)
            {
                throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));
            }

            Dictionary<int, string> KeyValuePair = new Dictionary<int, string>();
            Array EnumValues = Enum.GetValues(typeOfProperty);
            foreach (var item in EnumValues)
            {
                KeyValuePair.Add((int)item, item.ToString());
            }

            var selectList = new SelectList(KeyValuePair, "Key", "Value");
            return htmlHelper.DropDownListFor(modelExpression, selectList, firstElement);
        }
    }

そしてそれを私のページで次のように使用しました

Html.EnumDropDownListFor(m => m.AccountType, ContextConstants.defaultSelectionString)
于 2013-03-27T00:27:21.857 に答える