0

这很好玩。

好的,我有以下型号

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; }

}

我的类型在哪里:

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.

任何人都可以提供任何形式的工作,因为我很想使用我的:'(

一如既往,为我的无知道歉。

4

1 回答 1

2

在扩展方法的签名中,您有以下第二个参数:

Expression<Func<TModel, TProperty[]>> expression, 

这基本上意味着表达式必须返回一个TProperty=>的数组TProperty[]

而在您的视图模型中,您有一个List<T>

public List<MyTypes> EnergyTypeList { get; set; }

在您的视图中,您正在使用:

model => model.EnergyTypeList

您的代码不起作用,因为List<EnergyTypeList>EnergyTypeList[].

所以你有不同的可能性。要么更改视图模型中的类型以匹配助手中的类型,要么使用更改助手以使用 List 甚至更好的IEnumerable<TProperty>. 这样扩展方法甚至可以使用数组。

于 2012-07-05T15:21:04.743 回答