ドロップダウンリストについて学び、 Scott Guのブログ のようにnerddinnerのRSVP作成ページをHtml.DropDownListで追加しようとしています。利用可能なディナーを一覧表示します。
ドロップダウンリストにデータを入力することはできますが、必要な値(「サンプルディナー2」)を事前に選択するためのドロップダウンを取得できません。イニシライザーを使用して、dbにいくつかのディナーオブジェクトをシードします。データベースは、EFの「コードファーストアプローチ」を使用したSQL CE4です。申し訳ありませんが、これは一般的な問題であり、質問するのは嫌ですが、正直なところ、これにはかなりの時間を費やしていますが、機能させることができません。
ViewModel
public class RSVPViewModel
{
public SelectList DinnersList { get; set; }
public RSVP Rsvp { get; set; }
public string SelectedItem { get; set; }
}
コントローラー
//
//GET: /RSVP/Create
public ActionResult Create()
{
RSVP rsvp = new RSVP();
string selected = "Sample Dinner 2";
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title", selected);
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp, SelectedItem = selected };
return View("Create", viewModel);
}
表示
@Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList)
HTML結果
<select data-val="true" data-val-number="The field DinnerID must be a number." data-val-required="The DinnerID field is required." id="Rsvp_DinnerID" name="Rsvp.DinnerID">
<option value="1">Sample Dinner 1</option>
<option value="2">Sample Dinner 2</option>
</select>
したがって、ページが読み込まれるときに、値が「SampleDinner2」のドロップダウンリストを事前に選択していません。選択して[送信]をクリックすると、リストに[OK]と表示され、正しいDinnerIDが設定されます。
これも試してください:
@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
ただし、Rsvp.DinnerIDを設定またはバインドしません。
これはリストから事前選択しますが、バインドしません(またはRsvp.DinnerIDを設定します)
@Html.DropDownList("DinnersList")
私はそれをmvc3のままにしておきたいので、ViewModelアプローチ(ViewDataなし)を使用して、できればHtml.DropDownListFor(Html.DropDownListではなく)を使用して強い型で実装したいと思います。この場合、Viewbagは不要のようです。
ありがとう!
Edit1
SelectListItemsのselectListを使用する必要があると考えて、この冗長なアプローチを試しました。
RSVP rsvp = new RSVP();
string selected = "2";
List<SelectListItem> dinners = new List<SelectListItem>();
foreach (Dinner dinner in dbc.Dinners.ToList())
{
SelectListItem slDinner = new SelectListItem();
slDinner.Value = dinner.DinnerID.ToString();
slDinner.Text = dinner.Title;
slDinner.Selected = (slDinner.Value == selected);
dinners.Add(slDinner);
}
var dinnersList = new SelectList(dinners, "Value", "Text", selected);
var viewModel = new RSVPViewModel { DinnersList = dinnersList, Rsvp = rsvp, SelectedItem = selected };
しかし、まだ仕事はありません。 @ Html.DropDownListFor ..のViewModelSelectedItemプロパティを使用する必要がありますか?何かのようなもの :
@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
しかし、Rsvp.DinnerIDを設定するために選択した値を取得する方法。それはバインディングと呼ばれていると思います。
ここ と ここ を読んだ後、HtmlDropDownlistForがドロップダウンで正しいアイテムを自動的に選択する方法を最終的に理解しましたモデルに基づいて-RSVPでdinnerIDを選択します(dinner.dinnerIDへの外部キー)により、Dinner.DinnerIDのリストを含むドロップダウンでその値が事前に選択されます。必要ありませんまだSelectListまたはViewModelのselectedValueについて考えます。
解決策:
//
//GET: /RSVP/Create
public ActionResult Create()
{
//automatically preselects matching DinnerID in the Dinner dropdownlist
var rsvp = new RSVP {DinnerID = 2 };
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title");
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp};
return View("Create", viewModel);
}
SelectList
コンストラクター 使用しているのは、選択した値を提供することになっていますが、選択したテキストを提供しています。あなたは試してみたいかもしれません:
int selected = 2;
Html.DropDownListは、バインドされたプロパティがintの場合にのみ機能します。名前付き列挙型などの他のタイプでは、デフォルトで最初の項目になります。
モデルにプロパティを追加し、intと入力します。これにより、維持しようとしている列挙型がラップされます。
public myEnumType myProperty {get; set;} // don't bind this to Html.DropDownList
public myEnumType myPropertyAsInt {
get {return (int)this.myProperty; }
set {this.myProperty = (myEnumType)value; }
} // bind this instead
SelectListでSelectedを使用する必要はありません-Html.DropDownListは正常に同期します。
QUERY STRING with same nameがある場合は注意してください。これにより、その動作が上書きされます。同じ名前のHIDDENFIELDSについてはわかりません。
例えば。
DropDownListForは、見つかった場合、DinnerIDのクエリ文字列の値を使用します
Html.DropDownListはintプロパティ、DropDownListForも受け入れますが、何をしているのか注意する必要があります。 ASP.NET MVC 3のSelectExtensions.csを調べたところ、次のことがわかりました。
DropDownList( "XyField"、 "default")を使用してDropDownを作成する場合は、選択リストをViewBag.XyFieldに配置する必要があり、DropDownList()がこれを正しく処理します。
DropDownListFor(m => m.XyField、...)を使用すると、次のように、選択リストを明示的に渡すことができます。DropDownListFor(m => m .XyField、ViewBag .XyFieldList as IEnumerable)
これを行うと、次のことが起こります。
ここでの注意:選択リストをViewBag.XyFieldに保存した場合、モデルにアクセスする前に検索されます。「selectList.ToString()」と「selectList [i」を比較したくない] .Value」をクリックして、オプションを事前に選択します。選択リストを別の場所に保存してください!
面白いことに、DropDownList()から期待するのと同じように、暗黙の選択リストでDropDownListForを使用できます。この場合、リストをViewBag.XyFieldに保存することもできます。これを機能させるには、2番目のパラメーターとしてnullを指定してヘルパーを呼び出す必要があります。DropDownListFor(m => m .XyField、null)
次に、選択リストがViewBag.XyFieldからプルされ、上記のリストのステップ3はスキップされます。したがって、XyFieldがモデル状態の場合、これは選択リスト内の独自のSelectedプロパティよりも優先されますが、それ以外の場合、選択リストは「そのまま」使用されます。
あいさつロルフ