ASP.NET MVC强类型绑定模型的Yes/No单选按钮

141

有人知道如何将ASP.NET MVC中的强类型模型的布尔属性与是/否单选按钮绑定吗?

模型

public class MyClass
{
     public bool Blah { get; set; }
}

查看

<%@  Page Title="blah"  Inherits="MyClass"%>
    <dd>
        <%= Html.RadioButton("blah", Model.blah) %> Yes
        <%= Html.RadioButton("blah", Model.blah) %> No
    </dd>

感谢

解决方案:

感谢 Brian 给的指导,但他所写的正好相反。因此 -

<%@  Page Title="blah"  Inherits="MyClass"%>
<dd>
    <%= Html.RadioButton("blah", !Model.blah) %> Yes
    <%= Html.RadioButton("blah", Model.blah) %> No
</dd>

4
这些解决方案的“问题”(我在我的项目中使用Ben Cull风格)是你不能对它们进行标签。两个单选按钮输入将具有相同的id和名称,因此,如果您使用Html.LabelFor,则会将其链接到具有该id的DOM中的第一个单选按钮输入。就像我说的那样,我正在使用这些解决方案来表示布尔字段的单选按钮,我只想让人们知道标签会有点不正常。 - Gromer
2
请查看 Jeff Bobish 的答案,了解如何优雅地解决标签问题。 - René
8个回答

206

如果您正在使用MVC 3和Razor,您还可以使用以下内容:

@Html.RadioButtonFor(model => model.blah, true) Yes
@Html.RadioButtonFor(model => model.blah, false) No

77
第二个参数已被选择,因此在布尔值为false时使用!来选择没有值。
<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 

60

以下是一个更完整的示例,使用fieldset以实现无障碍访问,并将第一个按钮指定为默认选项。如果没有fieldset,则无法通过编程方式确定单选按钮所在的整个组。

模型

public class MyModel
{
    public bool IsMarried { get; set; }
}

视图

<fieldset>
    <legend>Married</legend>

    @Html.RadioButtonFor(e => e.IsMarried, true, new { id = "married-true" })
    @Html.Label("married-true", "Yes")

    @Html.RadioButtonFor(e => e.IsMarried, false, new { id = "married-false" })
    @Html.Label("married-false", "No")
</fieldset>

您可以向匿名对象添加@checked参数,将单选按钮设置为默认值:

new { id = "married-true", @checked = 'checked' }

请注意,您可以通过将truefalse替换为字符串值来绑定到一个字符串。


您应该实际上使用 new { id = Html.Id("married-true") },可以减少生成的 id 前缀可能存在的作用域问题。 - eoleary

26

在Ben的答案基础上稍作修改,我为ID添加了属性以便使用标签。

<%: Html.Label("isBlahYes", "Yes")%><%= Html.RadioButtonFor(model => model.blah, true, new { @id = "isBlahYes" })%>
<%: Html.Label("isBlahNo", "No")%><%= Html.RadioButtonFor(model => model.blah, false, new { @id = "isBlahNo" })%>

希望这能有所帮助。


7
通常标签在单选按钮后面。 - Daniel Imms
6
在单选按钮周围放置标签是完全有效的。 - Scott Baker

23

在常规HTML中,在单选按钮周围添加标签标签将修复“labelfor”问题:

<label><%= Html.RadioButton("blah", !Model.blah) %> Yes</label>
<label><%= Html.RadioButton("blah", Model.blah) %> No</label>

现在点击文本会选择相应的单选按钮。


8

或者MVC 2.0:

<%= Html.RadioButtonFor(model => model.blah, true) %> Yes
<%= Html.RadioButtonFor(model => model.blah, false) %> No

5
如果我可以插话一句,我认为有比现有答案更干净的方法来重用单选按钮功能。
假设您在ViewModel中有以下属性:
Public Class ViewModel
    <Display(Name:="Do you like Cats?")>
    Public Property LikesCats As Boolean
End Class

您可以通过可重用的编辑器模板公开该属性:

首先,创建文件Views/Shared/EditorTemplates/YesNoRadio.vbhtml

然后将以下代码添加到YesNoRadio.vbhtml中:

@ModelType Boolean?

<fieldset>
    <legend>
        @Html.LabelFor(Function(model) model)
    </legend>

    <label>
        @Html.RadioButtonFor(Function(model) model, True) Yes
    </label>
    <label>
        @Html.RadioButtonFor(Function(model) model, False) No
    </label>
</fieldset>

您可以通过在您的视图中手动指定模板名称来调用属性编辑器:

@Html.EditorFor(Function(model) model.LikesCats, "YesNoRadio")

优点:

  • 可以在 HTML 编辑器中编写 HTML,而不是在代码后端附加字符串。
  • 保留 DisplayName DataAnnotation(数据注释)。
  • 允许点击标签切换单选按钮。
  • 在表单中维护最少的代码(1 行)。如果渲染方式有问题,请联系模板。

这很好,但是布尔类型的第三个选项怎么办?@Html.RadioButtonFor(Function(Model) Model.IsVerified, True) <span>是</span> @Html.RadioButtonFor(Function(Model) Model.IsVerified, False) <span>否</span> @Html.RadioButtonFor(Function(Model) Model.IsVerified, Nothing)) <span>待定</span> - JoshYates1980

1
我最终将其打包成扩展方法,这样就可以同时生成标签和单选框,并且不必费心指定自己的ID:
public static class HtmlHelperExtensions
{
    public static MvcHtmlString RadioButtonAndLabelFor<TModel, TProperty>(this HtmlHelper<TModel> self, Expression<Func<TModel, TProperty>> expression, bool value, string labelText)
    {
        // Retrieve the qualified model identifier
        string name = ExpressionHelper.GetExpressionText(expression);
        string fullName = self.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        // Generate the base ID
        TagBuilder tagBuilder = new TagBuilder("input");
        tagBuilder.GenerateId(fullName);
        string idAttr = tagBuilder.Attributes["id"];

        // Create an ID specific to the boolean direction
        idAttr = String.Format("{0}_{1}", idAttr, value);

        // Create the individual HTML elements, using the generated ID
        MvcHtmlString radioButton = self.RadioButtonFor(expression, value, new { id = idAttr });
        MvcHtmlString label = self.Label(idAttr, labelText);

        return new MvcHtmlString(radioButton.ToHtmlString() + label.ToHtmlString());
    }
}

使用方法:

@Html.RadioButtonAndLabelFor(m => m.IsMarried, true, "Yes, I am married")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接