2013-08-30 4 views
42

Я видел несколько потоков на этом, но ни один из них не применяется к MVC4, потому что метода/помощника расширения RadioButtonFor html не существует.Список перечислений MVC4 и список переключателей

Скажем, у меня есть список перечислимую - т.е. Airlines:

public enum Airlines 
{ 
    Unknown = 0, 
    BritishAirways = 1, 
    VirginAtlantic = 2, 
    AirFrance = 3 
} 

Как я могу связать это со списком кнопок радио на мой взгляд, и быть в состоянии получить выбранный элемент? Как насчет того, чтобы сказать «выбрать один элемент», если нет выбора?

ответ

15

Что вы подразумеваете под RadioButtonFor не существует? Я использую MVC4 и использую это в своем коде. Для получения списка можно задать несколько тем же имя

@Html.RadioButtonFor(x => x.Airlines, Airlines.Unknown) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.BritishAirways) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.VirginAtlantic) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.AirFrance) 

они будут привязаны к модели так далее постбэк вы увидите Airlines установить на выбранном пункт и при загрузке страницы кнопка согласования радио будет выбрана.

+0

Я думаю, что Ахмед имел в виду, что 'RadioButtonFor' не существуют * до * до MVC4 и о том, что он примеры обнаружил, что не использовал вспомогательный метод. –

+0

Как бы вы добавляли метки с правильными атрибутами 'for'? –

+0

Я не уверен, что я следую. Как правило, со списком, подобным этому, у меня только 1 ярлык наверху, выберите лучший ... –

40

Вы можете создать собственный шаблон редактора для перечисления Airlines, который отобразит список переключателей. В вашей модели у вас будет свойство типа Airlines и отметьте это свойство атрибутом Required и установите ErrorMessage = "select one item". Не забудьте включить проверку jQuery для проверки на стороне клиента, если вы этого хотите, обычно просто нужно добавить @Scripts.Render("~/bundles/jqueryval") в свой макет или представление. Если вы не используете проверку jQuery, вам нужно будет сделать свойство nullable на модели, потому что перечисления просто установлены на первое значение по умолчанию, поэтому MVC не будет считать его недопустимым. Помните, что если вы измените свойство на nullable, вам также потребуется изменить тип модели вашего шаблона редактора и на значение NULL.

UPDATE

Чтобы включить редактор шаблонов для отображения списка кнопки радио для любого перечислимого, изменить шаблон к следующему:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    @Html.RadioButtonFor(m => m, value) 
    @Html.Label(value.ToString()) 
} 

ORIGINAL

редактор шаблонов , Airlines.cshtml, в Просмотров \ Shared \ EditorTemplates каталог:

@model MvcTest.Models.Airlines 
@foreach (var value in Enum.GetValues(typeof(MvcTest.Models.Airlines))) 
{ 
    @Html.RadioButtonFor(m => m, value) 
    @Html.Label(value.ToString()) 
} 

Модель:

public class TestModel 
{ 
    [Required(ErrorMessage = "select one item")] 
    public Airlines Airline { get; set; } 
} 

Методы действия:

public class HomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    { 
     return View(new TestModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(TestModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      return RedirectToAction("Index"); 
     } 

     return View(model); 
    } 
} 

Вид:

@model MvcTest.Models.TestModel 
@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
<h2>Index</h2> 
@using (Html.BeginForm()) 
{ 
    @Html.EditorFor(m => m.Airline) 
    <input type="submit" value="Submit" /> 
    @Html.ValidationSummary(false) 
} 
+0

Спасибо! Я попробую это и скоро вернусь к вам. Что делать, если я не хочу, чтобы определенное перечисление отображалось в списке? Допустим, что все перечисления, с которыми я имею дело, будут иметь «Неизвестный». как я могу убедиться, что он не будет отображаться, но также убедиться, что в списке выбрано значение? –

+1

ОК, это не работает для меня. Я не получаю список переключателей, а вместо этого просто текстовое поле. как я могу сделать частичный вид, возможно, и дать ему перечисление и получить частичное представление enum и в общих чертах выплевывать переключатели для каждого элемента в перечислениях, но также иметь привязку postback/submit к выбранному значению модели представления? –

+0

Если вы хотите сохранить определенное значение из списка, просто поместите оператор 'if' в цикле и проверьте его. Создание частичного представления вместо шаблона редактора должно быть довольно простым, разница - это просто семантика, потому что шаблоны редактора - это частичные виды. Просто создайте частичный вид в любом каталоге * view \ controller *, который вы хотите, хотя его размещение в общем каталоге может иметь больше смысла, а затем скопировать код из шаблона редактора в него. Вместо использования '@ Html.Partial (" partialViewName ", model)' и передайте перечисление из вашей основной модели представления в качестве модели. – asymptoticFault

28

Я предлагаю подобный подход к другим ответам , но со следующими шаблон редактора; EnumRadioButtonList.cshtml, в Views \ Shared \ EditorTemplates каталоге:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    var id = TagBuilder.CreateSanitizedId(string.Format(
     "{0}_{1}_{2}", ViewData.TemplateInfo.HtmlFieldPrefix, Model.GetType(), value)); 
    <div> 
     @Html.RadioButton(string.Empty, value, value.Equals(Model), new { id }) 
     @Html.Label(value.ToString(), new { @for = id }) 
    </div> 
} 

HTML-id каждой кнопки радио должно быть уникальным.Поэтому вышеприведенный код префикс id с именем связанного свойства с помощью ViewData.TemplateInfo.HtmlFieldPrefix. Это гарантирует уникальное значение id s, если модель содержит несколько свойств, которые использовали это перечисление, и если этот шаблон редактора использовался для каждого из них.

Соответствующий label для каждого переключателя будет правильно установлен его атрибут for. Это означает, что пользователь может выбрать радиокнопку, щелкнув текст ярлыка, намного больший и лучший клик, чем сам переключатель.

Для MVC модель привязки, радио-кнопки будут иметь их HTML name значение свойства устанавливается равным имущества, указанного в EditorFor вызова (Airline в этом сценарии).

Чтобы использовать его:

@Html.EditorFor(m => m.Airline, "EnumRadioButtonList") 
+1

Мне нравится этот подход, работает с удовольствием – sacha

+0

Это решение отлично подходит для редактирования страницы. Однако на странице «Создать», где еще нет выделенного элемента для переключателя enum, я получаю «Ссылка объекта не установлена ​​на экземпляр объекта». Любая работа вокруг этой проблемы? – corix010

+1

Я подозреваю, что «Модель», которую вы передаете, является «null» ... –

2

Я улучшил высокий номинальный ответ на asymptoticfault немного, чтобы отразить выбранные значения тоже. Сохранить это как EnumRadioButton.cshtml для ваших общих видов EditorTemplates папки:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    if (Equals(Model, value)) 
    { 
     @Html.RadioButtonFor(m => m, value, new {@checked = "checked"}) 
    } 
    else 
    { 
     @Html.RadioButtonFor(m => m, value) 
    } 

    @Html.Label(value.ToString()) 
} 

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

@Html.EditorFor(item => Model.MyEnumType, "EnumRadioButton")