asp.net-mvc MVC4 枚举和单选按钮列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18542060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:08:14  来源:igfitidea点击:

MVC4 enum and radio button list

asp.net-mvcasp.net-mvc-4

提问by Ahmed ilyas

I have seen a few threads on this but none seem to apply to MVC4 because the RadioButtonFor html extension method/helper does not exist.

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

Say I have an enum list - i.e Airlines:

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

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

How can I bind this to a Radio button list on my view and be able to retrieve the selected item? What about being able to say "select one item" if there is no selection made?

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

回答by asymptoticFault

You can create a custom Editor Template for the enum Airlinesthat will render a radio button list. In your Model you will have a property of type Airlinesand tag this property with the Requiredattribute and set ErrorMessage = "select one item". Don't forget to include the jQuery validation for client side validation if you want it, usually just have to add @Scripts.Render("~/bundles/jqueryval")on your Layout or View. If you don't use the jQuery validation you will need to make the property nullable on the model because enums are just set to the first value by default so MVC will not see it as invalid. Remember if you change the property to nullable you will also need to change the Model type of your Editor Template to nullable as well.

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

UPDATE

更新

To enable the Editor Template to render a radio button list for any enum, change the template to the following:

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

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

ORIGINAL

原来的

The Editor Template, Airlines.cshtml, in the Views\Shared\EditorTemplatesdirectory:

编辑模板,Airlines.cshtml,在视图\共享\ EditorTemplates目录:

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

The Model:

该模型:

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

The action methods:

动作方法:

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);
    }
}

The view:

风景:

@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)
}

回答by Richard Ev

I suggest a similar approach to the other answers, but with the following editor template; EnumRadioButtonList.cshtml, in the Views\Shared\EditorTemplatesdirectory:

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

The HTML idof each radio button needs to be unique. Therefore the above code prefixes the idwith the bound property's name by means of using ViewData.TemplateInfo.HtmlFieldPrefix. This ensures unique ids if the model contained multiple properties that used this enum, and if this editor template was used for each of them.

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

The accompanying labelfor each radio button will have its forattribute correctly set. This means that the user can select a radio button by clicking the label text, a much bigger and better click target than just the radio button itself.

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

For MVC model binding, the radio buttons will all have their HTML nameproperty value set to that of the property that was specified in the EditorForcall (Airlinein this scenario).

对于 MVC 模型绑定,单选按钮的 HTMLname属性值都将设置为EditorFor调用中指定的属性值(Airline在本场景中)。

To use it:

要使用它:

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

回答by Matt Bodily

What do you mean by RadioButtonFor doesn't exist? I use MVC4 and use that in my code. For a list you can set multiple to the same name

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)

these will be tied to the model so on postback you will see Airlines set to the selected item and when loading the page the matching radio button will be selected.

这些将与模型相关联,因此在回发时您将看到 Airlines 设置为所选项目,并且在加载页面时将选择匹配的单选按钮。

回答by Richie

I improved the highest rated answer by asymptoticfaulta bit to reflect selected values too. Save this as EnumRadioButton.cshtml to your shared views EditorTemplates folder:

我通过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())
}

Usage:

用法:

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

回答by Dangeresque

I was able to combine some of the approaches from other answers with some added features:

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

EnumRadioButtonList.cshtml

枚举RadioButtonList.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>
}

This uses EnumHelper.GetSelectList()as a sort of hack so that you can use display attributes with your enum members:

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

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

Usage:

用法:

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

Yields:

产量:

Image

图片

I'm also using the Bootstrap radio button styles with a separate helper for the inline version:

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

EnumRadioButtonListInline.cshtml

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>
}