我正在使用带有Razor和C#的ASP.NET MVC3。我正在制作各种表单构建器,因此我有一个具有以下对象集合的模型:
public class MyFormField
{
public string Name { get; set; }
public string Value { get; set; }
public MyFormType Type { get; set; }
}
MyFormType只是一个枚举,告诉我表单字段是复选框,文本框还是文件上传,或者其他什么。我的编辑器模板看起来像这样(参见评论):
〜/查看/ EditorTemplates / MyFormField.cshtml
@model MyFormField
@{
switch (Model.Type)
{
case MyFormType.Textbox:
@Html.TextBoxFor(m => m.Value)
case MyFormType.Checkbox:
@Html.CheckBoxFor(m => m.Value) // This does not work!
}
}
我尝试将m.Value
转换/转换为CheckBoxFor()的lambda表达式中的bool,但是这引发了错误。我只是手动构造一个复选框输入,但CheckBoxFor()似乎做了两件我似乎无法复制的事情:
有没有人知道在字符串上使用CheckBoxFor()的方法,或者手动复制其功能的方法,以便我可以使这个工作?
答案 0 :(得分:12)
您还可以在viewmodel上添加一个属性:
public class MyFormField
{
public string Name { get; set; }
public string Value { get; set; }
public bool CheckBoxValue
{
get { return Boolean.Parse(Value); }
}
public MyFormType Type { get; set; }
}
你的观点是这样的:
@model MyFormField
@{
switch (Model.Type)
{
case MyFormType.Textbox:
@Html.TextBoxFor(m => m.Value)
case MyFormType.Checkbox:
@Html.CheckBoxFor(m => m.CheckBoxValue) // This does work!
}
}
如果要避免异常,请使用Boolean.TryParse。
答案 1 :(得分:11)
一种方法是创建自己的htmlhelper扩展方法。
public static MvcHtmlString CheckBoxStringFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> expression)
{
// get the name of the property
string[] propertyNameParts = expression.Body.ToString().Split('.');
string propertyName = propertyNameParts.Last();
// get the value of the property
Func<TModel, string> compiled = expression.Compile();
string booleanStr = compiled(html.ViewData.Model);
// convert it to a boolean
bool isChecked = false;
Boolean.TryParse(booleanStr, out isChecked);
TagBuilder checkbox = new TagBuilder("input");
checkbox.MergeAttribute("id", propertyName);
checkbox.MergeAttribute("name", propertyName);
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("value", "true");
if (isChecked)
checkbox.MergeAttribute("checked", "checked");
TagBuilder hidden = new TagBuilder("input");
hidden.MergeAttribute("name", propertyName);
hidden.MergeAttribute("type", "hidden");
hidden.MergeAttribute("value", "false");
return MvcHtmlString.Create(checkbox.ToString(TagRenderMode.SelfClosing) + hidden.ToString(TagRenderMode.SelfClosing));
}
用法与CheckBoxFor helper相同(e.Value是一个字符串)
@Html.CheckBoxStringFor(e => e.Value)
答案 2 :(得分:4)
使用Checkbox,这种简单方法可以正常使用
@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)
答案 3 :(得分:0)
我也有这个问题,但无法修改视图模型。试过mdm20s解决方案,但我怀疑它不适用于集合属性(它不会将索引添加到名称和id,如本机html助手)。要解决此问题,您可以使用Html.CheckBox。它添加了正确的索引,您可以自己传递复选框的值。
如果你真的想使用一个表达式,你总是可以编写一个类似于mdm20s的包装器,但是在TryParse之后替换所有内容。
return Html.CheckBox("propertyName", isChecked)
。显然,您还需要添加using System.Web.Mvc.Html
。