1

MVC HtmlHelper.DropDownFor メソッドは、使用するのが実にイライラすることがあります。多くの場合、選択内容が残っていないか、コントロールが正しくバインドされていません。列挙型からドロップダウンを設定するカスタム HTML ヘルパーをどのように作成しますか?

4

1 に答える 1

1

私はこれを理解するために最後の数時間を費やしたので、私が見つけたものを共有することもできます. あらゆる種類の順列を試し、テスト アプリを作成してさまざまなオプションを試し、多くの記事を検索した結果、自分に合ったものを見つけました。

最初に言及するポイント。SelectList クラスは 4 つのパラメーターを取ります (最後の 3 つはオプションです)。選択した値 (最後のパラメーター) を指定しない場合、SelectListItem オブジェクトで設定した選択値がクリアされます (それらのリストを作成したと仮定します)。アイテムの Selected プロパティの 1 つを true に設定していたので、しばらくイライラしましたが、SelectList オブジェクトを作成すると、常に false に設定されていました。

参照用の SelectList の MVC ソースは次のとおりです。

public class SelectList : MultiSelectList
{
    public SelectList(IEnumerable items)
        : this(items, null /* selectedValue */)
    {
    }

    public SelectList(IEnumerable items, object selectedValue)
        : this(items, null /* dataValuefield */, null /* dataTextField */, selectedValue)
    {
    }

    public SelectList(IEnumerable items, string dataValueField, string dataTextField)
        : this(items, dataValueField, dataTextField, null /* selectedValue */)
    {
    }

    public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue)
        : base(items, dataValueField, dataTextField, ToEnumerable(selectedValue))
    {
        SelectedValue = selectedValue;
    }

    public object SelectedValue { get; private set; }

    private static IEnumerable ToEnumerable(object selectedValue)
    {
        return (selectedValue != null) ? new object[] { selectedValue } : null;
    }
}

その小さなポイントを過ぎたら、ヘルパーにリストからアイテムを正しく選択させ、値を正しくバインドさせました。だからここに私が作成したヘルパーメソッドがあります(最初のメソッドは別の投稿からのものでしたが、それは私にとっては正しく機能しませんでした):

public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null) where TProperty : struct, IConvertible
{
    if (!typeof(TProperty).IsEnum)
        throw new ArgumentException("TProperty must be an enumerated type");

    var selectedValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model.ToString();
    var selectList = new SelectList(from value in EnumHelper.GetValues<TProperty>()
                                    select new SelectListItem
                                                {
                                                    Text = value.ToDescriptionString(),
                                                    Value = value.ToString()
                                                }, "Value", "Text", selectedValue);

    return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}

(EnumHelper.GetValues と ToDescriptionString は、指定された型の列挙値のリストを返し、列挙型の説明の EnumMember 値プロパティを取得するヘルパー メソッドです) 必要に応じて、そのコードを投稿できます。

上記のコードの秘訣は、選択された値だけでなく、値とテキストのプロパティが何であるかを SelectList に伝えることでした。

于 2013-01-21T15:10:01.983 に答える