2008-11-19 8 views
30

Я правильно думаю, что после его создания невозможно установить выбранное значение в классе C# SelectList? Разве это не глупо?Установить выбранное значение в SelectList после создания экземпляра

+1

Я должен согласиться с вами, что это глупо. Похоже, что SelectList был специально «nerfed», чтобы заставить вас создавать более чистые (и тяжелые) модели. Частным случаем этого является необходимость повторного использования списка выбора в таблице, где каждая строка должна вывести свое выбранное значение из другого списка в вашей модели представления. Если вы хотите использовать SelectList, вам действительно нужно создать массив SelectList, каждый из которых предварительно назначен с выбранным значением, так как нет возможности выбрать его «на лету» непосредственно перед тем, как использовать его в коде зрения бритвы для этой конкретной строки. – Johncl 2011-09-27 07:34:28

ответ

18

Я думаю, что вы сражаетесь с каркасом. Данные, поступающие в ваши представления, должны создаваться на последней возможной минуте (LPM).

Мышление таким образом, SelectList является типом для подачи HTML-помощника DropDownList. Это НЕ место для хранения данных, когда вы решаете, как его обрабатывать.

Лучшим решением было бы получить ваши данные в List<T> и затем инициализировать SelectList (ы), когда вам нужно.Непосредственная выгода от этой практики является то, что она позволяет повторно использовать List<T> для более чем одного DropDownList, таких как:

Country of birth 
Country of residence 

These SelectLists все использовать список Страны типа List<Country>.

Вы можете использовать List<T> в «последнюю минуту», как в этом примере:

public class TaxCheatsFormViewModel 
{ 
    private List<Country> countries { get; set; } 

    public TaxCheat Cheat { get; private set; } 
    public SelectList CountryOfBirth { get; private set; } 
    public SelectList CountryOfResidence { get; private set; } 
    public SelectList CountryOfDomicile { get; private set; } 

    public TaxCheatsFormViewModel(TaxCheat baddie) 
    { 
     TaxCheat = baddie; 
     countries = TaxCheatRepository.GetList<Country>(); 
     CountryOfBirth = new SelectList(countries, baddie.COB); 
     CountryOfResidence = new SelectList(countries, baddie.COR); 
     CountryOfDomicile = new SelectList(countries, baddie.COD); 
    } 
} 

Суть в том, что вы должны сохранить ваши данные в List<T>, пока вы на самом деле нужно вывести его; последняя возможная минута (LPM).

0

Вы имеете в виду клиентскую сторону, в браузере?

var select = document.getElementById('mySelect'); 
select.options[newIndex].selected = true; 
3

Свойство «SelectedValue» доступно только для чтения. Установка его в конструкторе - единственный способ.

Tor, SelectList - это конструкция ASP.NET MVC, используемая для создания раскрывающегося списка. Выполнение этого по-своему тоже должно работать, но SelectList должен сделать это для вас (а не в JS), если это будет сделано правильно.

+8

Почему, для любви к Богу, это только для чтения? И почему вы не можете манипулировать элементами после создания экземпляра? И почему тогда он не может быть выставлен как массив readonly? Этот тип данных выходит за рамки меня! – 2008-11-19 13:54:58

+0

Если вам это не нравится, напишите свою собственную версию. Это не так сложно, парень. – Will 2008-11-19 13:56:15

+15

@ will: Правда, но я не думаю, что я единственный, кто испытывает эти чувства к классу SelectList. Должны ли мы все писать сами? – 2009-02-02 09:10:16

1

Я думаю, вы можете сделать это в контроллере. Если вы собираетесь отобразить выпадающий список с именем/идентификатором StateCode, вы можете установить выбранное состояние с помощью этого кода после создания SelectList:

ViewData ["StateCode"] = "VT";

Похоже, что HTML-помощник выпадающего списка ищет элемент ViewData с тем же именем, что и создаваемый выпадающий список.

Я не думаю, что мне нравится использовать эту технику, но, похоже, она работает.

Я согласен с тем, что класс SelectList немного слаб на данный момент. Я хотел бы иметь возможность создать SelectList, а затем выбрать значение позже либо значением, либо текстом.

+0

Я заметил, что он начинает проявляться, когда вы используете регулярную коллекцию в контроллере и selectlist только в самый последний момент. Хотя мне это не очень нравится, это отнимает много трения ... – 2009-02-02 09:08:56

0

Объект SelectList является readonly после его создания. если вы хотите, чтобы выбрать то, что вам лучше сделать это нравится:

<%= Html.DropDownList("clientId", ViewData["clients"] as List<SelectListItem>,)%> 

А в коде позади:

ViewData["clientId"] = "ASD"; //This should be the value of item you want to select 
    ViewData["clients"] = clientItemList; //List<SelectListItem> 
+0

Я стараюсь держаться подальше от кода, потому что это будет распространять код между моим контроллером, моим представлением и моим кодом. Теперь я создаю экземпляр SelectListItem в представлении. Не так, как я предпочитаю, но это только то, как куки рушится. – 2009-03-12 08:55:35

0

могли бы сделать это довольно легко с JQuery;

$(function() { 
    $("#myselectlist option[@value='ItemToSelectValue'].attr('selected', 'true'); 
}); 
0

Мне нужно выпадающее меню в редактируемой сетке с предварительно выбранными значениями выпадающего списка. Afaik, данные списка выбора предоставляются контроллером для представления, поэтому он создается до того, как его потребляет. Когда представление потребляет SelectList, я передаю его специальному помощнику, который использует стандартный помощник DropDownList. Итак, довольно легкое решение imo. Угадайте, что он вписывается в дух ASP.Net MVC на момент написания; когда вы не счастливы свернуть свой собственный ...

public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue) 
{ 
    return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue)); 
} 
4

Потому что это такой высокий результат в Google, я обеспечиваю, что я нашел, чтобы работать здесь (несмотря на возраст):

Если вы используете сильно типизированных (т.е. модель имеет назначенный тип), SelectedValue, предоставленный конструктору SelectList, перезаписывается значением объекта, используемого для Модели страницы.

Это хорошо работает на странице редактирования, но не для Create, когда вы хотите предварительно выбрать конкретное значение, поэтому одно обходное решение - это просто назначить правильное значение для построенного по умолчанию объекта, который вы передаете в представление в качестве модели. , например.

var model = new SubjectViewModel() 
{ 
    Subject = new Subject(), 
    Types = data.SubjectTypes.ToList() 
} 
model.Subject.SubjectType = model.Types.FirstOrDefault(t => t.Id == typeId); 
ViewData.Model = model; 
return View(); 

поэтому код в моем Create View, который выглядит следующим образом:

Html.DropDownListFor(model => model.Subject.SubjectTypeId, new SelectList(model.Types, "Id", "Name")) 

возвращает список падения вниз со значением I, назначенного в качестве SelectedValue в списке.

4

Я знаю, что это старый вопрос, но он может помочь кому-то там. Я сделал то, что было похоже на то, что сделал Эрик. Я только что создал новый SelectList от моего существующего ...

SelectList myList = GetMySelectList(); 
SelectListItem selected = myList.FirstOrDefault(x => x.Text.ToUpper().Contains("UNITED STATES")); 
if (selected != null) 
{ 
    myList = new SelectList(myList, "value", "text", selected.Value); 
} 
0

Я согласен с @awrigley и другим, что лучше, чтобы загрузить выбранное значение с помощью конструктора SelectList в обычном случае, когда у вас есть один DropDownList , Однако иногда необходимо установить выбранное значение в представлении, например, когда у вас есть страница с n одинаковыми выпадающими списками. Поскольку создание таких коллекций в контроллере нецелесообразно, и может даже не знать заранее, сколько вы выпадающих списков вам нужно, лучший подход - создать один экземпляр в viewmodel в качестве шаблона без выбранного значения, а затем динамически создать остальные динамически на представлении.

Я часто сталкиваюсь с этим при повторении списка дочерних элементов при просмотре представлений, когда детям нужны выпадающие списки. В таких случаях вы можете сделать это, как это, с одной строкой кода:

@Html.DropDownListFor(x => myViewModelFieldName, new SelectList(Model.MyRawSelectListFromMyViewModel.Select(x=> new {x.Value, x.Text}), "Value", "Text", TheValueYouWantToSelect))