私の見解には次のコードがあります:
<%= Html.ListBoxFor(c => c.Project.Categories,
new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
<%= Html.ListBox("MultiSelectList",
new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
唯一の違いは、最初のヘルパーが強く型付けされている(ListBoxFor)こと、そして選択された項目を表示できない(1,2)ですが、項目がリストに表示されている場合などです。より単純なListBox期待どおりに動作しています。
ここには明らかに何かが欠けています。私は2番目のアプローチを使用できますが、これは本当に私を悩ませているので、それを理解したいと思います。
参考までに、私のモデルは:
public class ProjectEditModel
{
public Project Project { get; set; }
public IEnumerable<Project> Projects { get; set; }
public IEnumerable<Client> Clients { get; set; }
public IEnumerable<Category> Categories { get; set; }
public IEnumerable<Tag> Tags { get; set; }
public ProjectSlide SelectedSlide { get; set; }
}
ListBoxの名前をProject.Categories(モデルに一致)に変更したところ、アイテムの選択に失敗しました。
<%= Html.ListBox("Project.Categories",
new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
私は明らかにここで起こっている魔法を理解していません。
わかりました、これは純粋に名前を付けています。たとえば、これは機能します...
<%= Html.ListBox("Project_Tags",
new MultiSelectList(Model.Tags, "Id", "Name", Model.Project.Tags.Select(t => t.Id)))%>
...フィールド名はProject.TagsではなくProject_Tagsであるため、実際には、TagsまたはProject.Tags以外のものが機能します。これがなぜ問題を引き起こすのか(エンティティ名と一致することを除いて)わかりません。また、これを調べて調べることができるほど十分ではありません。
私はこの問題に出くわしましたが、ついに問題が命名規則にあることに気付きました。
SelectListまたはMultiSelectListを含むViewBagまたはViewData popertyに、選択したアイテムを含むプロパティモデルと同じ名前を付けることはできません。少なくとも、ListBoxForまたはDropDownListForヘルパーを使用している場合はそうではありません。
次に例を示します。
public class Person
{
public List<int> Cars { get; set; }
}
[HttpGet]
public ActionResult Create()
{
//wont work
ViewBag.Cars = new SelectList(carsList, "CarId", "Name");
//will work due to different name than the property.
ViewBag.CarsList = new SelectList(carsList, "CarId", "Name");
return View();
}
//View
@Html.ListBoxFor(model => model.Cars, ViewBag.CarsList as SelectList)
これを行う方法は他にもたくさんあると思いますが、私の問題は解決しました。誰かの役に立つことを願っています!
私もこのまったく同じ問題に悩まされており、ListBoxとListBoxForで同じ問題が発生しました。
何をしても、ListBoxForで選択を行うことができません。 ListBoxに変更して、バインドしているデータのプロパティ名以外の名前を付けると、選択が発生します。
しかし、ListBoxForを使用しておらず、データがたとえばモデルクラス(Model.Departments)内にあるため、コントローラーに戻る途中でモデルバインディングが取得されず、プロパティがnullになります。
[〜#〜] edit [〜#〜]誰かが投稿した解決策をここに見つけました。 ListBoxForで値を選択する際の課題
正解は、うまく機能しないことです。そのため、MVCコードを読み取りました。 IConvertibleを実装し、TypeConverterも作成する必要があります。
そのため、私のインスタンスでは、人々が国のリストから選択できるように、Country
クラスを用意しました。それを選択する喜びはありません。私は、オブジェクトがselectedItems
とlistitems
との比較と等しいことを期待していましたが、そうではありません。 MultiListItem
が機能し、選択されたアイテムを正しく取得するという事実にもかかわらず、モデルにバインドされた瞬間は、オブジェクトインスタンスの文字列表現が文字列"value"
(または名前に一致するかどうかのチェックに基づいています)欠落している場合)SelectItemList
のアイテムのリストで。
したがって、IConvertible
を実装し、ToString
の値と一致するSelectItemList
から文字列値を返します。たとえば、私の場合、CountryCode
はSelectItem
Value
プロパティにシリアル化されたため、ToString IConvertible
でCountryCode
を返しました。これですべてが正しく選択されます。
TypeConverter
が途中で使用されていることを指摘します。今回はその逆です。そのCountrycode
が戻ってきて、「EN」はCountry
クラスインスタンスに変換する必要があります。そこがTypeConverter
の出番です。また、このアプローチの使用がいかに難しいかを理解したのもこの頃です。
pS Category
クラスでは、IConvertible
を実装する必要があります。私の会社のエンティティフレームワークからの場合は、部分クラスを使用してIConvertible
を実装し、ToString
を実装して、あなたが書いたTypeConverter
で装飾する必要があります。 。
また、コントローラーでc.Project.CategoriesのModelStateをクリアしてみることもできます。
[HttpPost]
public ActionResult Index(ModelType model)
{
ModelState.Remove("Project.Categories");
return View("Index", model);
}
次の構文を使用します。
<%= Html.ListBoxFor(c => c.Project.Categories,
new MultiSelectList(Model.Categories, "Id", "Name"))%>
ここで、c.Project.CategoriesはIEnumerable<int>
。
私の英語でごめんなさい。幸運を!
これを試して
<%= Html.ListBoxFor(c => c.Project.Categories,
new MultiSelectList(
Model.Categories
,"Id"
,"Name"
,Model.Project.Tags.Select(
x => new SelectListItem()
{
Selected = true,
Text = x.TEXT,
Value = x.ID.ToString()
}).ToList())
)
)%>
これは主な質問への回答ではありませんが、MVCが名前を生成すると、Project.TagsのようなものをProject_Tagsに変換し、ピリオドをアンダースコアに置き換えます。
これを行う理由は、要素IDのピリオドが、CSSへのタグのクラスを持つProjectという名前の要素のように見えるためです。明らかに悪いことなので、行動を予測可能に保つためにアンダースコアに変換します。
最初の例では、
<%= Html.ListBoxFor(c => c.Project.Categories,
new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
リストボックスは、ページに提供されている厳密に型指定されたモデルのModel.Project.Categoriesにバインドしようとしています(ラムダ表記を使用)。 ListBoxForの2番目のパラメーターが何をしているのかわかりません。
ページに渡されるモデルは何ですか?
Html.ListboxForとHtml.Listboxは、リストボックスをデータソースにバインドしない場合に適切に機能します。私は意図された使用がこれだと思います:
// Model
public class ListBoxEditModel
{
public IEnumerable<Category> Categories { get; set; }
public IEnumerable<Category> SelectedCategories { get; set; }
}
ビューで:
@Html.ListBoxFor(m => m.SelectedCategories,
new MultiSelectList(Model.Categories, "Id", "Name"))
// or, equivalently
@Html.ListBox("SelectedCategories" ,
new MultiSelectList(Model.Categories, "Id", "Name"))
この場合、MultiSelectListで選択されている値を明示的に指定する必要がないことに注意してください。バインドするモデルが優先されます。