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