I\'m using ASP.NET MVC3 with Razor and C#. I am making a form builder of sorts, so I have a model that has a collection of the following object:
public class
I had this problem as well but was unable to modify the view model. Tried mdm20s solution but as i suspected it does not work on collection properties (it does not add the indexes to the names and ids like the native html helpers). To overcome this you can use the Html.CheckBox instead. It adds the proper indexes and you can pass the value of the checkbox yourself.
If you really want to use an expression you can always write a wrapper similar to mdm20s but replace everything after the TryParse with
return Html.CheckBox("propertyName", isChecked)
. Obviously you will need to add using System.Web.Mvc.Html
as well.
Use the Checkbox, this simple way works fine
@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)
One way is to create your own htmlhelper extension method.
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));
}
The usage is the same as CheckBoxFor helper (e.Value is a string)
@Html.CheckBoxStringFor(e => e.Value)
You could also add a property on your 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; }
}
Your view would be something like this:
@model MyFormField
@{
switch (Model.Type)
{
case MyFormType.Textbox:
@Html.TextBoxFor(m => m.Value)
case MyFormType.Checkbox:
@Html.CheckBoxFor(m => m.CheckBoxValue) // This does work!
}
}
Use Boolean.TryParse if you want to avoid exceptions.