#.net #asp.net-mvc #asp.net-mvc-3 #razor
#.net #asp.net-mvc #asp.net-mvc-3 #razor
Вопрос:
У меня проблема с предварительным выбором элементов в listbox. Я использую механизм просмотра razor с mvc 3. Я знаю, что есть несколько сообщений с той же проблемой, но они не работают для меня.
Код в классе:
public class Foo{
private int _id;
private string _name;
public string Name{
get{
return _name;
}
public int Id {
get{
return _id;
}
}
Код в модели:
public class FooModel{
private readonly IList<Foo> _selectedFoos;
private readonly IList<Foo> _allFoos;
public IList<Foo> SelectedFoos{
get{ return _selectedFoos;}
}
public IList<Foo> AllFoos{
get{ return _allFoos;}
}
}
Код на cshtml:
@Html.ListBoxFor(model => model.Flatschels,
Model.AllFlatschels.Select(fl => new SelectListItem {
Text = fl.Name,
Value = fl.Id.ToString(),
Selected = Model.Flatschels.Any(y => y.Id == fl.Id)
}), new {Multiple = "multiple"})
Я пробовал много других вещей, но ничего не получалось. Надеюсь, кто-нибудь сможет помочь.
Ответ №1:
Я не могу толком объяснить почему, но мне удалось заставить это работать. Любой из них сработал:
@Html.ListBoxFor(m => m.SelectedFoos,
new MultiSelectList(Model.AllFoos, "ID", "Name"), new {Multiple = "multiple"})
@Html.ListBoxFor(m => m.SelectedFoos, Model.AllFoos
.Select(f => new SelectListItem { Text = f.Name, Value = f.ID }),
new {Multiple = "multiple"})
Проблема, похоже, в том, что выбранное свойство в SelectListItem игнорируется, и вместо этого вызывается ToString()
(!) метод, поэтому, если вам нужно добавить это в свой Foo
класс:
public override string ToString()
{
return this.ID;
}
Я предполагаю, что это как-то связано с возможностью сохранения между запросами (которые будут сведены к строкам, передаваемым по проводам), но это немного сбивает с толку!
Комментарии:
1. Большое спасибо. У меня получилось. Хотя сработал только второй код, и мне кажется, что это не из-за переопределенной toString(). Моим свойством Id было значение int, и я добавил ключ свойства, возвращающий уникальную строку (guid. toString()).
2. Странно. Не могу объяснить, что такое toString, но рад, что вы разобрались с этим 🙂
3. Это было определенно из-за toString(). Только что опубликовал вопрос на форуме Microsoft и надеюсь получить ответ и, возможно, информацию, почему (и как долго) это происходит в настоящее время.
4. Аналогичное поведение в Razor для MVC4. Ошибка на границе (по крайней мере, для ListBox(), которая не ожидает, что модель будет сравнивать элементы).
5. У меня тоже сработало! По какой-то причине следующее не сработало:
@Html.DropDownListFor(m => m.SelectedFoos, new MultiSelectList(Model.AllFoos), new {multiple = ""}
(где в моем случаеFoo
является перечислением, а не объектом кортежа. Единственное изменение, которое мне нужно было внести, былоDropDownListFor
->ListBoxFor
Ответ №2:
В MVC5 вы можете напрямую использовать ListBoxFor с multiselect. Убедитесь, что при загрузке представления в вашем SelectedItem должен быть список элементов.
@Html.ListBoxFor(m => m.SelectedItem, new MultiSelectList(Model.Item.ToList(), "Value", "Text"), new { @class = "form-control" })