Я сделал, чтобы редактор обработал по шаблону для пользовательского объекта. В том шаблоне редактора я использую несколько помощников DropDownListFor. В каждом из них я определяю уникальное свойство модели (с заданной величиной) и список выборки, содержащий все избранные опции.
Пример:
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
Я знаю, что значения опции заполняются (от просмотра источника) и что моя Модель передается в с корректным Значением идентификатора (DocumentCategoryType).
Когда представление представляется, нет никакого выбранного пункта в моем выпадающем, и поэтому оно принимает значение по умолчанию к первому (невыбранному) значению.
У кого-либо есть какие-либо идеи?
Спасибо.
Уф. В итоге я решил это вот так. Я надеюсь, что это будет исправлено в RTM.
<%if(Model!=null){ %>
<%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%>
<%}else{%>
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
<%}%>
Это подтверждено как ошибка @ aspnet.codeplex.com и ведет себя так только для строго типизированных представлений.
Обходной путь: заполните свой список выбора в коде представления
, например
<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>
Model.DocumentCategoryTypeList
Это, вероятно, ваша проблема. В SelectListitEs вы устанавливаете значение на вывод .toString ()?
var list = new List<SelectListItem>()
{
new SelectListItem()
{
Value = Category.Book.ToString(),
Text = "Book"
},
new SelectListItem()
{
Value = Category.BitsAndPieces.ToString(),
Text = "Bits And Pieces" },
new SelectListItem()
{
Value = Category.Envelope.ToString(),
Text = "Envelopes" }
};
работает для меня после этого. Это просто нужно уметь сопоставить значение от объекта
Мы также решили решение, заполнив новый SelectList
, в котором выбран соответствующий SelectListItem
, но создали этот метод расширения, чтобы сохранить вызов DropDownListFor
немного чище:
public static SelectList MakeSelection(this SelectList list, object selection)
{
return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}
Тогда ваш вызов DropDownListFor
изменится на:
<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>
Просмотр исходного кода ASP.NET MVC 2 позволяет найти некоторые решения этой проблемы. По сути, любой SelectListItem
в SelectList
, переданный во вспомогательном методе расширения, для свойства Selected
задано значение true, не имеет никакого отношения к < option>
визуализирован с атрибутом selected
, примененным к элементу.
Атрибут selected
в элементах
определяется путем
1) проверки того, что методу расширения вспомогательной функции был передан SelectList
. Если это null, платформа будет искать в ViewData значение, соответствующее ключу, который является свойством модели представления, для которого вы хотите отобразить раскрывающийся список. Если значение равно SelectList
, оно будет использоваться для рендеринга
, включая принятие любых выбранных значений, при условии, что состояние модели для свойства модели равно null.
2) Если SelectList
был передан во вспомогательный метод расширения, а состояние модели для свойства модели равно null, структура будет искать в ViewData значение по умолчанию, используя имя свойства модели. как ключ.Значение в данных представления преобразуется в строку, и любые элементы в SelectList
передаются методу вспомогательного расширения, у которых есть значение (если значение не задано, будет проверяться текст), которое соответствует значению по умолчанию. value будет иметь свойство Selected
, установленное на true, что, в свою очередь, отобразит
с атрибутом selected = "selected"
.
В совокупности есть два возможных варианта, которые я вижу, чтобы выбрать вариант и использовать строго типизированный DropDownListFor
:
Использование следующей модели представления
public class CategoriesViewModel
{
public string SelectedCategory { get; private set ; }
public ICollection<string> Categories { get; private set; }
public CategoriesViewModel(string selectedCategory, ICollection<string> categories)
{
SelectedCategory = selectedCategory;
Categories = categories;
}
}
действия контроллера
public class CategoriesController
{
[HttpGet]
public ViewResult Select()
{
/* some code that gets data from a datasource to populate the view model */
ICollection<string> categories = repository.getCategoriesForUser();
string selectedCategory = repository.getUsersSelectedCategory();
CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
this.ViewData["Categories"] = selectedCategory;
return View(model);
}
[HttpPost]
public ActionResult Select(CategoriesViewModel model)
{
/* some code that does something */
}
}
и в строго типизированном представлении
<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
действия контроллера
public class CategoriesController
{
[HttpGet]
public ViewResult Select()
{
/* some code that gets data from a datasource to populate the view model */
ICollection<string> categories = repository.getCategoriesForUser();
string selectedCategory = repository.getUsersSelectedCategory();
CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
return View(model);
}
[HttpPost]
public ActionResult Select(CategoriesViewModel model)
{
/* some code that does something */
}
}
и в строго типизированном представлении
<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>