Предварительный выбор элементов в Multiselect-Listbox (MVC3 Razor)

#.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" })