2016-11-21 1 views
6

私はMultiSelectListの使用に関する多くの記事を読んでいますが、DropDownListForで何が問題になっているのかまだ理解していません。私は同じView、ViewModelとうまく動作するデータを持つListBoxForを持っています。 ListBoxForにはないoptionLabelパラメータがあるため、DropDownListForを使用します。なぜDropDownListForはSubmitの後に複数選択を失うのですか?しかしListBoxForはしません。

ビューが最初に読み込まれると、DropDownListForとListBoxForの両方が複数の選択された項目を表示します。

Initial View

[送信]ボタンをクリックすると、選択した項目のコレクションはバックコントローラのアクションに大丈夫掲載されており、ビューはListBoxForはまだ両方の選択項目を示したが、DropDownListForは一つだけ選択した項目を示していると更新されます。

Refreshed View コントローラのアクションは次のようにMultiSelectListを構築されています

vm.TasksFilterGroup.Assignees = new MultiSelectList(employees, "Id", "FullName", new string[] { "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757", "51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" }); 

ビューのコードは次のようになります。

<div class="form-group"> 
 
    <label>ListBoxFor</label> 
 
    @Html.ListBoxFor(m => m.TasksFilterGroup.SelectedAssignees, Model.TasksFilterGroup.Assignees, new { @class = "form-control", multiple = "multiple" }) 
 
</div> 
 
<div class="form-group"> 
 
    <label>DropDownListFor</label> 
 
    @Html.DropDownListFor(m => m.TasksFilterGroup.SelectedAssignees, Model.TasksFilterGroup.Assignees, new { @class = "form-control", multiple = "multiple" }) 
 
</div>

なぜDropDownListForは、複数選択を失うん後に提出ListBoxForはありませんか?

答えて

15

メソッドの名前が暗示するように、DropDownListFor()<select>を作成するためのものである(1つのオプションを選択する)とListBoxFor()は、(複数のオプションを選択する)<select multiple>を作成するためのものです。どちらのメソッドも共通のコードを共有していますが、異なる結果が得られます。

multiple="multiple"属性を追加すると表示が変更されますが、これらのメソッドで実行されるコードの機能は変更されません。

あなたがsource codeを調べる場合は、DropDownListFor()のすべてのオーバーロードが最終的にprivate static MvcHtmlString DropDownListHelper()メソッドを呼び出すことに注意します、と同様にListBoxFor()は、最終的にprivate static MvcHtmlString ListBoxHelper()メソッドを呼び出します。

は、これらの両方の方法は、private static MvcHtmlString SelectInternal()メソッドを呼び出し、その差はListBoxHelper()allowMultiple = trueを通過しながらDropDownListHelper()allowMultiple = false通過することです。

SelectInternal()メソッド内で、コードのキー行はdefaultValueの値

object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string)); 

ある<option>要素のHTMLを構築するときに使用され、selected属性(複数可)を設定するために使用されています。

ListBoxFor()の場合、defaultValueの値は、SelectedAssigneesプロパティで定義された配列になります。 DropDownListFor()の場合、プロパティの値をstring(配列)にキャストできないため、nullを返します。

defaultValuenullあるので、<option>要素のどれもselected属性が設定されていないと、あなたは結合モデルを失います。

ビューにモデルを渡す前にGETメソッドでSelectedAssigneesの値を設定した場合は、前述の理由と同じ理由でDropDownListFor()を使用しているときに、そのいずれも選択されていないことがわかります。 SelectListを生成するためのコードがちょうど

vm.TasksFilterGroup.Assignees = new SelectList(employees, "Id", "FullName" }); 

でなければならないことも

注財産の価値があなたに結合するためにはポイントDropDownListFor()またはListBoxFor()方法のいずれかを使用するときに3番目のパラメータを設定することは(ありませんSelectedAssignees)は、どのオプションが選択されたかを決定します(3番目のパラメータはメソッドによって無視されます)。あなたがそれらのGuid値に一致するオプションを選択したい場合は、GETメソッドでは、

vm.TasksFilterGroup.SelectedAssignees= new string[]{ "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757", "51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" }; 
+1

この徹底した知識豊富な応答がはるかに高く評価されるを使用しています。ありがとうございました。 – RJBreneman

+0

これは非常に深い答えです。非常に洞察力のある。 – CodingYoshi

関連する問題