我已经看到了一些线程,但似乎没有一个适用于 MVC4,因为 RadioButtonFor html 扩展方法/帮助程序不存在。
假设我有一个枚举列表 - 即航空公司:
public enum Airlines
{
Unknown = 0,
BritishAirways = 1,
VirginAtlantic = 2,
AirFrance = 3
}
如何将其绑定到视图上的单选按钮列表并能够检索所选项目?如果没有选择,那么能够说“选择一项”怎么样?
我已经看到了一些线程,但似乎没有一个适用于 MVC4,因为 RadioButtonFor html 扩展方法/帮助程序不存在。
假设我有一个枚举列表 - 即航空公司:
public enum Airlines
{
Unknown = 0,
BritishAirways = 1,
VirginAtlantic = 2,
AirFrance = 3
}
如何将其绑定到视图上的单选按钮列表并能够检索所选项目?如果没有选择,那么能够说“选择一项”怎么样?
Airlines
您可以为将呈现单选按钮列表的枚举创建自定义编辑器模板。在您的模型中,您将拥有一个 type属性,并使用属性和 setAirlines
标记该属性。如果需要,不要忘记在客户端验证中包含 jQuery 验证,通常只需在布局或视图中添加即可。如果您不使用 jQuery 验证,则需要使模型上的属性可为空,因为枚举默认设置为第一个值,因此 MVC 不会将其视为无效。请记住,如果您将属性更改为可空,您还需要将编辑器模板的模型类型也更改为可空。Required
ErrorMessage = "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)
}
我建议对其他答案采用类似的方法,但使用以下编辑器模板;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.HtmlFieldPrefix
。id
如果模型包含使用此枚举的多个属性,并且每个属性都使用此编辑器模板,这将确保唯一的 s。
label
每个单选按钮的随附for
属性都将正确设置。这意味着用户可以通过单击标签文本来选择单选按钮,这是一个比单选按钮本身更大更好的点击目标。
对于 MVC 模型绑定,单选按钮的 HTMLname
属性值都将设置为调用中指定的属性值EditorFor
(Airline
在这种情况下)。
要使用它:
@Html.EditorFor(m => m.Airline, "EnumRadioButtonList")
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 设置为所选项目,并且在加载页面时将选择匹配的单选按钮。
我能够将其他答案中的一些方法与一些附加功能相结合:
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>
}
我通过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")