将多个radiobutton绑定到单个布尔值

时间:2016-03-23 12:07:33

标签: c# asp.net-mvc razor

背景

我有一个包含三个bools的模型

public class PageDataModel
{
    public bool setting1 { get; set; }
    public bool setting2 { get; set; }
    public bool setting3 { get; set; }
}

如果一个值为true,则其他值必须为false。

在我看来,我正在显示三个单选按钮:

Enter image description here

我的观点的剃刀代码:

<div class="row">
        <div class="radio">
            @if (Model.Setting1)
            {
                @Html.RadioButtonFor(m => m.Setting1,  "Setting1", new { Checked = "checked", Name = "Group"})
            }
            else
            {
                @Html.RadioButtonFor(m => m.Setting1, "Setting1", new { Name = "Group"})
            }

            @Html.Label("Setting1")
        </div>
        <div class="radio">
            @if (Model.Setting2)
            {
                @Html.RadioButtonFor(m => m.Setting2, "Setting2", new { Checked = "checked", Name = "Group" })
            }
            else
            {
                @Html.RadioButtonFor(m => m.Setting2, "Setting2", new { Name = "Group"})
            }
            @Html.Label("Setting2")
        </div>
        <div class="radio">
            @if (Model.Setting3)
            {
                @Html.RadioButtonFor(m => m.Setting3, "Setting3", new { Checked = "checked", Name = "Group" })
            }
            else
            {
                @Html.RadioButtonFor(m => m.Setting3, "Setting3", new { Name = "Group"})
            }
            @Html.Label("Setting3")
        </div>
        <button type="submit" class="btn btn-default">Save</button>
    </div>

在我的控制器中,我将返回一个模型,其中setting1设置为true:

var model = new PageDataModel
        {
            Setting1 = true,
            Setting2 = false,
            Setting3 = false
        };
        return View(model);

这项工作正常,页面加载了&#39;设置1&#39;选中单选按钮。

问题

当我提交表单时,发布的模型包含所有错误值,无论选中哪个单选按钮。

我尝试更改&#34;设置1&#34;为true / false,但这对返回的数据没有影响。

我相当确定我没有正确设置绑定,但我不确定我哪里出错了。

我发现的所有其他示例都将两个单选按钮绑定到一个bool值(例如,绑定到一个bool的是/否对的单选按钮)。我可以更改代码以使用一个int属性,但我想使用bools来解决这个问题。

我做错了什么?我在这里滥用单选按钮吗?

1 个答案:

答案 0 :(得分:4)

从技术上讲,只要您将值设置为true,这样就可以正常工作。例如:

@Html.RadioButtonFor(m => m.setting1, true)

这样,如果选择了收音机,它将发布true

然而,这里不可逾越的问题是,这不是无线电设计的功能。收音机是组的一部分,由name属性的值决定。这会导致选择一个无线电取消选择具有相同name属性的所有无线电。但是,使用RadioButtonFor将根据属性名称为每个无线电提供不同的名称。换句话说,你最终得到:

<input type="radio" id="setting1" name="setting1" value="true" />
<input type="radio" id="setting2" name="setting2" value="true" />
<input type="radio" id="setting3" name="setting3" value="true" />

然后,每个无线电将成为不同组的一部分,每个组只包含一个无线电(意味着每个无线电将默认选择)。您可以覆盖name属性,但随后发布的值将不再绑定到实际属性。例如,如果你有:

<input type="radio" id="setting1" name="setting" value="true" />
<input type="radio" id="setting2" name="setting" value="true" />
<input type="radio" id="setting3" name="setting" value="true" />

这样他们现在都是同一个广播组的一部分,价值会发布到setting总是是真的。

无论多么短暂,都没有办法让这项工作像这样。您可以做的是使用其他属性代理值。

public class PageDataModel
{
    public bool setting1 { get; set; }
    public bool setting2 { get; set; }
    public bool setting3 { get; set; }

    public string SelectedSetting
    {
        get
        {
            if (setting1) return "setting1";
            if (setting2) return "setting2";
            if (setting3) return "setting3";
            return null; // or you can set a default here
        }
        set
        {
            switch (value)
            {
                case "setting1":
                    setting1 = true;
                    break;
                case "setting2":
                    setting2 = true;
                    break;
                case "setting3":
                    setting3 = true;
                    break;
            }
        }
    }
}

然后,在您看来:

<div class="radio">
    <label>
        @Html.RadioButtonFor(m => m.SelectedSetting, "setting1")
        @Html.DisplayNameFor(m => m.setting1)
    </label>
</div>
<div class="radio">
    <label>
        @Html.RadioButtonFor(m => m.SelectedSetting, "setting2")
        @Html.DisplayNameFor(m => m.setting2)
    </label>
</div>
<div class="radio">
    <label>
        @Html.RadioButtonFor(m => m.SelectedSetting, "setting3")
        @Html.DisplayNameFor(m => m.setting3)
    </label>
</div>

现在,无线电将全部分组为&#34; SelectedSetting&#34;并将发布到SelectedSetting属性。该属性上的自定义getter和setter确保将在实际settingX属性上设置正确的布尔值。