这很有趣。
好的,我有以下模型:
public class My : BusinessCategory
{
[Display(Name = "What types of energy do you use?")]
public List<MyTypes> MyTypeList { get; set; }
public bool? FirstOption { get; set; }
public bool? SecondOption{ get; set; }
public bool? ThirdOption{ get; set; }
public bool? FourthOption { get; set; }
}
MyTypes:
public class MyTypes
{
public int MyTypeId { get; set; }
public string MyTypeName { get; set; }
public bool? MyTypeValue { get; set; }
}
我的控制器如下:
public ActionResult My(Guid id)
{
try
{
var model = Model(id);
SetMyTypeList(model.My);
ViewBag.MyTypeMe = new MultiSelectList(model.My.MyTypeList, "MyTypeValue", "MyTypeName");
return View(model.My);
}
catch (Exception ex)
{
ExceptionHelper.WriteLog(ex);
return RedirectToAction("Error");
}
}
private void SetMyTypeList(My model)
{
model.MyTypeList = new List<MyTypes>();
model.MyTypeList.Add(new MyTypes { MyTypeId = 1, MyTypeName = GetName.GetDisplayName(model, m => m.FirstOption), MyTypeValue = model.FirstOption });
model.MyTypeList.Add(new MyTypes { MyTypeId = 2, MyTypeName = GetName.GetDisplayName(model, m => m.SecondOption), MyTypeValue = model.SecondOption});
model.MyTypeList.Add(new MyTypes { MyTypeId = 3, MyTypeName = GetName.GetDisplayName(model, m => m.ThirdOption), MyTypeValue = model.ThirdOption});
model.MyTypeList.Add(new MyTypes { MyTypeId = 4, MyTypeName = GetName.GetDisplayName(model, m => m.FourthOption), MyTypeValue = model.FourthOption });
}
public static string GetDisplayName<TModel, TProperty>(TModel model, Expression<Func<TModel, TProperty>> expression)
{
return ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, new ViewDataDictionary<TModel>(model)).DisplayName;
}
最后观点如下:
@model Valpak.Websites.HealthChecker.Models.My
@{
ViewBag.Title = "My";
}
<h2>
My</h2>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>My Management</legend>
<div style="text-align: left; padding-left: 47%;">
@Html.ListBoxFor(model => model.MyTypeList, ViewBag.MyTypeMe as MultiSelectList)
@Html.CheckBoxListFor(model => model.MyTypeList, ViewBag.EnergyTypeMe as MultiSelectList, Model.ReviewId)
</div>
<p>
<input type="submit" value="Continue" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Cancel and return to categories", "BusinessSummary", new { id = Model.ReviewId })
</div>
CheckboxListFor,如果它正常,将使用以下扩展名:
public static class HtmlHelper
{
//Extension
public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty[]>> expression, MultiSelectList multiSelectList, object htmlAttributes = null)
{
//Derive property name for checkbox name
MemberExpression body = expression.Body as MemberExpression;
string propertyName = body.Member.Name;
//Get currently select values from the ViewData model
TProperty[] list = expression.Compile().Invoke(htmlHelper.ViewData.Model);
//Convert selected value list to a List<string> for easy manipulation
List<string> selectedValues = new List<string>();
if (list != null)
{
selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); });
}
//Create div
TagBuilder divTag = new TagBuilder("div");
divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);
//Add checkboxes
foreach (SelectListItem item in multiSelectList)
{
divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
"value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
propertyName,
item.Value,
selectedValues.Contains(item.Value) ? "checked=\"checked\"" : "",
item.Text);
}
return MvcHtmlString.Create(divTag.ToString());
}
}
有人可以用非常简单的术语解释(我有点密集),为什么我可以使用ListBoxFor示例但是当我使用复选框时,这会导致以下错误?
CS0411: The type arguments for method 'Extensions.HtmlHelper.CheckBoxListFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,TProperty[]>>, System.Web.Mvc.MultiSelectList, System.Guid, object)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
任何人都可以提供任何类型的工作,因为我非常想使用我的:'(
一如既往,为我的无知道歉。
答案 0 :(得分:2)
在扩展方法的签名中,您有以下第二个参数:
Expression<Func<TModel, TProperty[]>> expression,
这基本上意味着表达式必须返回TProperty
=&gt;的数组。 TProperty[]
而在您的视图模型中,您有一个List<T>
:
public List<MyTypes> EnergyTypeList { get; set; }
在你正在使用的视图中:
model => model.EnergyTypeList
您的代码无效,因为List<EnergyTypeList>
与EnergyTypeList[]
不同。
所以你有不同的可能性。您可以更改视图模型中的类型以匹配帮助程序中的类型,也可以使用更改帮助程序来使用List或更好的IEnumerable<TProperty>
。这样,即使使用数组,扩展方法也能正常工作。