2009-04-23 2 views
121

Я создаю selectList в своем контроллере для отображения в представлении.Как я могу заставить этот ASP.NET MVC SelectList работать?

Я пытаюсь создать его на лету, Сорта вещь .. как это ...

myViewData.PageOptionsDropDown = 
    new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15"); 

собирает, но вывод плохо ...

<select id="PageOptionsDropDown" name="PageOptionsDropDown"> 
    <option>10</option> 
    <option>15</option> 
    <option>25</option> 
    <option>50</option> 
    <option>100</option> 
    <option>1000</option> 
</select> 

Обратите внимание, что элемент не выбран?

Как это исправить?

+1

Шесть ответов ... один ... Избраный no upvotes:/Я дам ему +1 – womp

+0

возможный дубликат [Как добавить элемент в SelectList в ASP.net MVC] (http://stackoverflow.com/questions/668589/how-can-i -add-an-item-to-a-selectlist-in-asp-net-mvc) –

ответ

122

Это, как я это делаю

IList<Customer> customers = repository.GetAll<Customer>(); 
IEnumerable<SelectListItem> selectList = 
    from c in customers 
    select new SelectListItem 
    { 
     Selected = (c.CustomerID == invoice.CustomerID), 
     Text = c.Name, 
     Value = c.CustomerID.ToString() 
    }; 

На второй взгляд, я не уверен, что я знаю, что вы после ...

+2

Спасибо, что помогли мне разобраться в этом материале. – Cadoo

+6

Не исправляет проблему с выбранным элементом, но это отличный способ избежать магических строк для избранных списков! Cheers –

+9

Чтобы исправить проблему с выбранным элементом, добавьте следующий код: 'SelectList sList = новый SelectList (selectList,« Текст »,« Значение », выбранный);' где 'selected' - текущий выбранный клиент – jao

45

Используя конструктор, который принимает items, dataValueField, dataTextField, selectedValue в качестве параметров:

ViewData["myList"] = 
       new SelectList(new[] { "10", "15", "25", "50", "100", "1000" } 
       .Select(x => new {value = x, text = x}), 
       "value", "text", "15"); 

Затем на ваш взгляд:

<%=Html.DropDownList("myList") %> 
+3

приятный чувак :) Мне нравится! я пытался это сделать .. но я не мог получить .Select (..) часть .. приятно :) Я попробую его дома, позже :) –

+1

Heya Cagdas. отлично работает, за исключением того, что выбранное поле не выбрано. Есть идеи? это ошибка в материалах MVC? –

+2

Выбранный элемент работает, когда вы добавляете элемент SelectList в объект ViewData (как в ViewData ["myList"] = new SelectList ..), а затем визуализируйте его с помощью <% = Html.DropDownList ("myList")%>. Я не мог заставить выбранный элемент работать, не делая этого таким образом. Weird. –

0

Это может быть так, что у вас есть некоторые неясности в вашем ViewData:

Взгляните Here

68

I u зе метод расширения:

использование

var departmentItems = departments.ToSelectList(d => d.Code + 
               " - " + d.Description, 
               d => d.Id.ToString(), 
               " - "); 

var functionItems = customerFunctions.ToSelectList(f => f.Description, 
                f => f.Id.ToString(), 
                " - "); 

с

public static class MCVExtentions 
{ 
    public static List<SelectListItem> ToSelectList<T>(
     this IEnumerable<T> enumerable, 
     Func<T, string> text, 
     Func<T, string> value, 
     string defaultOption) 
    { 
     var items = enumerable.Select(f => new SelectListItem() 
            { 
             Text = text(f), 
             Value = value(f) 
            }).ToList(); 
     items.Insert(0, new SelectListItem() 
        { 
         Text = defaultOption, 
         Value = "-1" 
        }); 
     return items; 
    } 
} 
+0

nice. Я добавил выбранный параметр Func, defaultValue и вторую перегрузку без каких-либо значений по умолчанию чтобы указать, и это работает. Кстати, если вы хотите сделать возвращаемый тип IEnumerable , вы можете использовать синтаксис возврата доходности, чтобы сделать этот вид действительно чистым –

11

Это вариант:

myViewData.PageOptionsDropDown = new[] 
{ 
new SelectListItem { Text = "10", Value = "10" }, 
new SelectListItem { Text = "15", Value = "15", Selected = true } 
new SelectListItem { Text = "25", Value = "25" }, 
new SelectListItem { Text = "50", Value = "50" }, 
new SelectListItem { Text = "100", Value = "100" }, 
new SelectListItem { Text = "1000", Value = "1000" }, 
} 
+0

и что выбрано ' –

+0

new SelectListItem {Selected = true, Text = "15", Value = "15"} для выбранного значения. – Cadoo

+0

oops, да, забыл включить свойство «Selected», спасибо Cadoo =) – murki

1

Используя ваш пример это работало для меня:

контроллер:

ViewData["PageOptionsDropDown"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); 

вид:

<%= Html.DropDownList("PageOptionsDropDown")%> 
+0

Да, это тоже работает для меня. В моем случае список - это объект модели объекта. Контроллер: ViewData ["Категории"] = новый SelectList (db.Categories.ToList(), "CategoryId", "CategoryName", "15"); Вид: Html.DropDownList ("CategoryId", (SelectList) ViewData ["Категории"], "--select--") –

1

Я просто побежал, как это и не было никаких проблем,

public class myViewDataObj 
    { 
     public SelectList PageOptionsDropDown { get; set; } 
    } 

public ActionResult About() 
     { 
      myViewDataObj myViewData = new myViewDataObj(); 
      myViewData.PageOptionsDropDown = 
        new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); 

      ViewData["myList"] = myViewData.PageOptionsDropDown; 
      return View(); 
     } 

и

<%=Html.DropDownList("myList") %> 

он также работал, если вы сделаете это,

public ActionResult About() 
     { 
      myViewDataObj myViewData = new myViewDataObj(); 
      myViewData.PageOptionsDropDown = 
        new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }); 

      ViewData["myListValues"] = myViewData.PageOptionsDropDown; 
      ViewData["myList"] = "15"; 
      return View(); 
     } 

и

<%=Html.DropDownList("myList",(IEnumerable<SelectListItem>)ViewData["myListValues"]) %> 
4

Кажется, если у вас есть сильно типизированной вам необходимо изменить идентификатор выпадающего списка, так что НЕ - имя свойства наследуемого класса. Затем вам нужно поместить некоторую логику в свой метод редактирования (POST), чтобы вытащить выбранное значение из FORMCollection и поместить его в свой экземпляр перед выполнением изменений.

Это, конечно, немного странно, но я попробовал, и он работает.

Итак, если у вас есть поле под названием CountryId, и вы показываете список названий стран, сделайте выпадающий список идентификатором CountryName, а не CountryId, а затем в сообщении вы можете сделать что-то с помощью Collection [ "Имя страны"].

+1

Да, у меня была эта же проблема.Простое изменение имени работало. Благодаря! – davekaro

12

Проблема в том, что SelectList работает так, как было разработано. Ошибка в дизайне. Вы можете установить выбранное свойство в SelectedItem, но это будет полностью проигнорировано, , если вы пройдете список с помощью GetEnumerator() (или если Mvc сделает это за вас). Вместо этого Mvc создаст новые элементы SelectListItems.

Вы должны использовать SelectList ctor с помощью SelectListItem [], Text-Name, Value-Name и SelectedValue. Имейте в виду, чтобы передать как SelectedValue значение VALUE из SelectListItem, которое вы хотите выбрать, а не сам SelectListItem! Пример:

SelectList sl = new SelectList(new[]{ 
    new SelectListItem{ Text="one", Value="1"}, 
    new SelectListItem{ Text="two", Value="2"}, 
    new SelectListItem{ Text="three", Value="3"} 
}, "Text", "Value", "2"); 

(не проверял это, но у меня была такая же проблема)

то второй вариант получит выбранный = «выбран» атрибут. Это выглядит как старые добрые DataSets ;-)

1
MonthRepository monthRepository = new MonthRepository(); 
IQueryable<MonthEntity> entities = monthRepository.GetAllMonth(); 
List<MonthEntity> monthEntities = new List<MonthEntity>(); 

foreach(var r in entities) 
{ 
    monthEntities.Add(r); 
} 

ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars"); 
0

значение, выбранное в модели использует вместо элемента по умолчанию. (я согласен, я не читал все сообщения)

0

Я не могу вспомнить, как MVC 1 была установка, но мне кажется, что он хочет список выбора с таким же именем, как поле он принадлежал тоже ...

То, что я нашел, как кто-то сказал выше, заключается в том, что мои списки выбора не работали в mvc2, когда ViewData, которые они были отправлены, так же назывались так же, как и поле.

Например:

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>

работы при

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>

не работает, как имя ViewData "ForID" называется так же, как поле он работает для

1

Я делаю это вот так:

List<SelectListItem> list = new List<SelectListItem>{ 
new SelectListItem {Selected = true, Text = "Select", Value = "0"}, 
new SelectListItem {Selected = true, Text = "1", Value = "1"}, 
new SelectListItem {Selected = true, Text = "2", Value = "2"} 
}; 
return list.ToArray(); 

ToArray() заботится о проблемах.

0

Возможное объяснение состоит в том, что значение selectlist, которое вы связываете, не является строкой.

Итак, в этом примере параметр 'PageOptionsDropDown' содержит строку в вашей модели? Потому что, если это не так, выбранное значение в списке не будет отображаться.

0

Если вы посмотрите в исходном коде MVC 2 по методу расширения Html.DropDownList, он никогда не проверяет свойство SelectedValue класса SelectList. Он будет только пытаться соответствовать вашей модели.

Все приведенные выше все являются вариантами темы, то есть как вы отправляете кучу данных в представление для выпадающего списка &, они все так же хороши, как и другие (более или менее) ,

Проблема в представлении. Либо создайте свой собственный метод расширения DropDownList, который будет уважать выбранное значение selectvalue, либо выполнить итерацию вручную. Что когда-либо лучше всего подходит для вас.

+0

@Franz Antesberger говорит почти то же самое. –

10

Если это буквально все, что вы хотите сделать, то просто объявить массив в строку фиксирует выбранную проблему элемента:

myViewData.PageOptionsDropDown = 
    new SelectList(new string[] {"10", "15", "25", "50", "100", "1000"}, "15"); 
2

Все эти ответы выглядят великолепно, но, кажется, что контроллер подготавливает данные для Просмотр в хорошо структурированном формате vs.позволяя просто пропустить IEnumerable <>, поставляемый с помощью модели, и создать стандартный список выбора, а затем позволить DefaultModelBinder доставить выбранный элемент обратно вам через параметр действия. Да, нет, почему бы и нет? Разделение проблем, да? Кажется странным иметь контроллер, чтобы что-то создать, поэтому пользовательский интерфейс и вид конкретных.

18

Строительство от ответа Thomas Stock, я создал эти перегруженные ToSelectList методы:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 

public static partial class Helpers 
{ 
    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, bool selectAll = false) 
    { 
     return enumerable.ToSelectList(value, value, selectAll); 
    } 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, object selectedValue) 
    { 
     return enumerable.ToSelectList(value, value, new List<object>() { selectedValue }); 
    } 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, IEnumerable<object> selectedValues) 
    { 
     return enumerable.ToSelectList(value, value, selectedValues); 
    } 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, bool selectAll = false) 
    { 
     foreach (var f in enumerable.Where(x => x != null)) 
     { 
      yield return new SelectListItem() 
      { 
       Value = value(f).ToString(), 
       Text = text(f).ToString(), 
       Selected = selectAll 
      }; 
     } 
    } 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, object selectedValue) 
    { 
     return enumerable.ToSelectList(value, text, new List<object>() { selectedValue }); 
    } 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, IEnumerable<object> selectedValues) 
    { 
     var sel = selectedValues != null 
      ? selectedValues.Where(x => x != null).ToList().ConvertAll<string>(x => x.ToString()) 
      : new List<string>(); 

     foreach (var f in enumerable.Where(x => x != null)) 
     { 
      yield return new SelectListItem() 
      { 
       Value = value(f).ToString(), 
       Text = text(f).ToString(), 
       Selected = sel.Contains(value(f).ToString()) 
      }; 
     } 
    } 
} 

В контроллере, вы можете сделать следующее:

var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" }; 
ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/); 

И, наконец, на ваш взгляд, говоря:

@Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable<SelectListItem>, "(Select one)") 

Это приведет к желаемому результату - конечно, вы можете lea ве вне "(Select one)" optionLabel выше, если вы не хотите, первый пустой элемент:

<select id="PageOptionsDropDown" name="PageOptionsDropDown"> 
<option value="">(Select one)</option> 
<option value="10">10</option> 
<option selected="selected" value="15">15</option> 
<option value="25">25</option> 
<option value="50">50</option> 
<option value="100">100</option> 
<option value="1000">1000</option> 
</select> 

Update: Пересмотренный листинг кода может быть found here с комментариями XML.

2

Простой:

string[] someName = new string[] {"10", "15", "25", "50", "100", "1000"}; 
myViewData.PageOptionsDropDown = new SelectList(someName, "15"); 
4

У меня была точно такая же проблема. Решение прост. Просто измените параметр «name», переданный помощнику DropDownList, на то, что не соответствует ни одному из свойств, существующих в вашей ViewModel. читайте здесь: http://www.dotnetguy.co.uk/post/2009/06/25/net-mvc-selectlists-selected-value-does-not-get-set-in-the-view

цитирую Дэн Уотсон:

В MVC, если вид сильно типизированных выбранный вариант в SelectList будет отменено, и выбранный вариант набора свойств на конструктор никогда не достигнет вместо этого будет выбран вид и первый вариант в раскрывающемся списке (почему все еще остается загадкой).

ура!

0

Если у вас есть коллекция в вашей модели, и ваш взгляд сильно типа, некоторые изменения, это будет работать:

@Html.DropDownListFor(x => x.RegionID, 
    new SelectList(Model.Regions,"RegionID", "RegionName", Model.RegionID)) 

-или-

@Html.DropDownList("RegionID", 
    new SelectList(Model.Regions, "RegionID", "RegionName", Model.RegionID)) 
6

Это очень просто получить SelectList и SelectedValue работает вместе, даже если ваше свойство не является простым объектом, например Int, String или Double.

Пример:

Предполагая, что наш объект Region-то вроде этого:

public class Region { 
    public Guid ID { get; set; } 
    public Guid Name { get; set; } 
} 

И ваша модель представления что-то вроде:

public class ContactViewModel { 
    public DateTime Date { get; set; } 
    public Region Region { get; set; } 
    public List<Region> Regions { get; set; } 
} 

Вы можете иметь код ниже:

@Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name")) 

Только если переопределить метод ToString объекта области к чему-то вроде:

public class Region { 
    public Guid ID { get; set; } 
    public Guid Name { get; set; } 

    public override string ToString() 
    { 
     return ID.ToString(); 
    } 
} 

Это есть 100% гарантия на работу.

Но я действительно считаю, что лучший способ получить SelectList 100%, работающий во всех системах циркуляции, - это использовать метод Equals для проверки значения свойства DropDownList или ListBox для каждого элемента коллекции предметов.

1

Если вы хотите передать какой-то случайный текст в DropDownList, например --Выбор-- вы можете легко сделать это, используя этот код:

@Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "Id", "Name"), "--Select--", new { @class = "form-control" }) 
Смежные вопросы