50

我已经看到了一些线程,但似乎没有一个适用于 MVC4,因为 RadioButtonFor html 扩展方法/帮助程序不存在。

假设我有一个枚举列表 - 即航空公司:

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

如何将其绑定到视图上的单选按钮列表并能够检索所选项目?如果没有选择,那么能够说“选择一项”怎么样?

4

5 回答 5

45

Airlines您可以为将呈现单选按钮列表的枚举创建自定义编辑器模板。在您的模型中,您将拥有一个 type属性,并使用属性和 setAirlines标记该属性。如果需要,不要忘记在客户端验证中包含 jQuery 验证,通常只需在布局或视图中添加即可。如果您不使用 jQuery 验证,则需要使模型上的属性可为空,因为枚举默认设置为第一个值,因此 MVC 不会将其视为无效。请记住,如果您将属性更改为可空,您还需要将编辑器模板的模型类型也更改为可空。RequiredErrorMessage = "select one item"@Scripts.Render("~/bundles/jqueryval")

更新

要使编辑器模板能够为任何枚举呈现单选按钮列表,请将模板更改为以下内容:

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

原来的

编辑器模板Airlines.cshtml位于Views\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)
}
于 2013-08-30T22:41:05.133 回答
33

我建议对其他答案采用类似的方法,但使用以下编辑器模板;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>
}

每个单选按钮的 HTMLid必须是唯一的。因此,上面的代码id通过 using 为绑定属性的名称添加前缀ViewData.TemplateInfo.HtmlFieldPrefixid如果模型包含使用此枚举的多个属性,并且每个属性都使用此编辑器模板,这将确保唯一的 s。

label每个单选按钮的随附for属性都将正确设置。这意味着用户可以通过单击标签文本来选择单选按钮,这是一个比单选按钮本身更大更好的点击目标。

对于 MVC 模型绑定,单选按钮的 HTMLname属性值都将设置为调用中指定的属性值EditorForAirline在这种情况下)。

要使用它:

@Html.EditorFor(m => m.Airline, "EnumRadioButtonList")
于 2014-01-10T15:27:58.433 回答
19

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 设置为所选项目,并且在加载页面时将选择匹配的单选按钮。

于 2013-08-30T22:25:05.743 回答
3

我能够将其他答案中的一些方法与一些附加功能相结合:

EnumRadioButtonList.cshtml

@model Enum
@foreach (var item in EnumHelper.GetSelectList(Model.GetType()))
{
    <div class="radio">
        <label>
            @Html.RadioButton(string.Empty, item.Value, Model.Equals(Enum.Parse(Model.GetType(), item.Value)))
            @item.Text
        </label>
    </div>
}

EnumHelper.GetSelectList()用作一种 hack,以便您可以将显示属性与枚举成员一起使用:

public enum TestEnum
{
    First,
    [Display(Name = "Second Member")]
    Second,
    Third
}

用法:

@Html.EditorFor(m => m.TestEnumProperty, "EnumRadioButtonList")

产量:

图片

我还使用 Bootstrap 单选按钮样式和内联版本的单独助手:

EnumRadioButtonListInline.cshtml

@model Enum
@foreach (var item in EnumHelper.GetSelectList(Model.GetType()))
{
    <label class="radio-inline">
        @Html.RadioButton(string.Empty, item.Value, Model.Equals(Enum.Parse(Model.GetType(), item.Value)))
        @item.Text
    </label>
}
于 2018-03-22T16:20:16.277 回答
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")
于 2016-07-29T07:51:47.767 回答