ASP.NET MVC:三态复选框
原因:ASP.NET MVC没有提供Tri-state checkbox组件,因为它只依赖于HTML中已经存在的标准元素。
解决方法:可以尝试使用JavaScript来实现Tri-state checkbox。可以参考这个解决方案。
另外,也可以通过添加新的HTML辅助器(HTML helpers)来实现类似于Web控件的功能。
作者并不期望ASP.NET MVC能够直接提供Tri-state checkbox组件,他只是在尝试寻求帮助来创建自己的组件。
ASP.NET MVC: Tri-state checkbox问题主要出现的原因是在渲染HTML内容时,无法直接给<input type="checkbox" />
元素添加indeterminate
属性。因此,需要使用JavaScript来获取该元素并设置indeterminate
属性。此外,模型绑定只会发生在实际发送的请求中的值上,因此对于未选中的复选框和indeterminate状态的复选框,它们在模型绑定中被视为相同的状态。
为了解决这个问题,可以采取以下几种方法:
1. 使用JavaScript来设置indeterminate属性:
// vanilla js document.getElementById("myChk").indeterminate = true; // jQuery $("#myCheck).prop("indeterminate", true);
2. 通过为每个复选框生成两个输入字段来解决模型绑定的问题,其中一个输入字段用于存储实际的值,另一个隐藏的输入字段用于确保即使复选框未被选中也会发送一个false值。例如:
<label > <input type="checkbox" name="chkEmpty"> Checkbox </label> <label > <input type="checkbox" name="chkChecked" checked> Checkbox with Checked </label> <label > <input type="checkbox" name="chkIndeterminate" id="chkIndeterminate"> <script> document.getElementById("chkIndeterminate").indeterminate = true; </script> Checkbox with Indeterminate </label> <label > <input name="RegularBool" type="checkbox" value="true"> <input name="RegularBool" type="hidden" value="false"> RegularBool </label>
3. 使用一个枚举类型来代替布尔类型,并为该属性创建一个EditorTemplate,以渲染一个包含实际要持久化的属性的隐藏输入字段和一个用于更新该属性的复选框控件。然后使用JavaScript来保持它们之间的同步。例如:
public enum CheckState { Checked, Indeterminate, Unchecked } public CheckState OpenTasks { get; set; }
Views/Shared/EditorTemplates/CheckState.cshtml
:
@Html.HiddenFor(model => model, new { @class = "tri-state-hidden" }) @Html.CheckBox(name: "", isChecked: (Model == CheckState.Checked), htmlAttributes: new { @class = "tri-state-box" })
// on load, set indeterminate $(".tri-state-hidden").each(function() { var isIndeterminate = this.value === ".Indeterminate"; if (isIndeterminate) { var $box = $(".tri-state-box[name='" + this.name + "'][type='checkbox']"); $box.prop("indeterminate", true); } }); // on change, keep synchronized $(".tri-state-box").change(function () { var newValue = this.indeterminate ? ".Indeterminate" : this.checked ? ".Checked" : ".Unchecked"; var $hidden = $(".tri-state-hidden[name='" + this.name + "'][type='hidden']"); $hidden.val(newValue); });
4. 根据领域模型的需求,可以考虑使用Yes,No,ⁿ/ₐ单选按钮作为替代方案。
以上是解决ASP.NET MVC中Tri-state checkbox问题的一些方法。根据具体情况选择合适的解决方案。
ASP.NET MVC: Tri-state checkbox问题的出现原因是tri-state复选框不是一个标准的HTML控件,因此在ASP.NET MVC中没有直接提供此控件。然而,有一种解决方法是创建一个TriStateCheckBox的扩展方法,可以通过在web.config文件中添加该方法类的命名空间来使用。
解决方法是在HtmlHelper
中添加一个TriStateCheckBox
(或者如果使用强类型的重载,则使用TriStateCheckBoxFor
)扩展方法,并将该扩展方法类的命名空间添加到web.config文件的namespaces
部分。关于实现的方法,可以参考codeplex上的InputExtensions源码,并根据该源码创建自己的扩展方法。
另外,如果在下一个ASP.NET MVC或MvcContrib版本中添加了TriStateCheckBox,那将非常好。然而,由于tri-state CheckBoxes不是标准的HTML控件,所以很不可能官方添加此控件。