Asp.net mvc 4 MVC4:使用lambdas模拟内置的HtmlHelper扩展

Asp.net mvc 4 MVC4:使用lambdas模拟内置的HtmlHelper扩展,asp.net-mvc-4,lambda,html-helper,Asp.net Mvc 4,Lambda,Html Helper,我正在尝试编写自己的Html助手方法,这些方法接受lambda表达式,比如内置的助手(TextBoxFor、CheckBoxFor、LabelFor等)。我在这方面找到了一些有用的信息(以及Scott Allen的),但我很难将这些信息整合在一起。我在泛型和lambdas之间的相互作用中迷失了方向。或者别的什么 我的案例与上面的示例略有不同——我正在尝试编写一个数据网格编辑功能,它允许对HTML表中的行进行就地编辑。(我在经典ASP中做过这样的事情,我正在尝试在MVC中实现。)网格编辑控件需要一

我正在尝试编写自己的Html助手方法,这些方法接受lambda表达式,比如内置的助手(TextBoxFor、CheckBoxFor、LabelFor等)。我在这方面找到了一些有用的信息(以及Scott Allen的),但我很难将这些信息整合在一起。我在泛型和lambdas之间的相互作用中迷失了方向。或者别的什么

我的案例与上面的示例略有不同——我正在尝试编写一个数据网格编辑功能,它允许对HTML表中的行进行就地编辑。(我在经典ASP中做过这样的事情,我正在尝试在MVC中实现。)网格编辑控件需要一点状态——一个行ID和一个URL来发布更改。因此,我的助手方法不会是HtmlHelper的静态扩展。至少我不这么认为。因此,我的问题不是关于网格编辑功能(我已经或多或少掌握了这一点),而是关于如何设置我的助手方法,使它们接受行为类似于内置助手的lambda。(我希望从视图中获得强类型的好处。我可以使用反射和字符串参数生成标记,但我知道我可以做得更好。)

到目前为止,我尝试在razor视图中使用它的地方是这样的——请注意GridEditor对象:

@foreach (var item in Model.Items)
{
    var ge = new GridEditor<MyProject.SomethingFromMyDataModel>(item.ID, "someUrl");
    <tr>
        <td>@ge.CheckBox(x => x.SomeBooleanProperty)</td>
        <td>@ge.TextBox(x => x.ATextProperty)</td>
        <td>@ge.DropDownList(x => x.SomeForeignKey, ViewBag.MyList as SelectList)</td>
        <td>@ge.Controls()</td>
    </tr>
}
@foreach(Model.Items中的变量项)
{
var ge=新的GridEditor(item.ID,“someUrl”);
@CheckBox(x=>x.SomeBooleanProperty)
@ge.TextBox(x=>x.ATextProperty)
@ge.DropDownList(x=>x.SomeForeignKey,ViewBag.MyList作为SelectList)
@ge.Controls()
}
这不起作用,但我希望它能让你知道我在努力做什么。我的GridEditor类是这样设置的。我有点抓紧救命稻草。。。。注意,我并没有包括所有内容——而是我认为相关的内容

public class GridEditor<TModel> where <TModel> : class
{
    public GridEditor(int rowID, string postUrl)
    {
    }

    public MvcHtmlString CheckBox<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
    {
    }
}
公共类GridEditor,其中:类
{
公共网格编辑器(int-rowID,string-postrl)
{
}
公共MvcHtmlString复选框(表达式)
{
}
}

不管怎样,就像我说的,这不管用。简而言之——我的问题是——我如何设置我的CheckBox(和类似的)方法,以便它们接受一个lambda,该lambda的强类型与传递给GridEditor的类型相同?

在熟睡之后,我发现答案非常简单。。。。因为GridEditor上的方法是实例(不是静态的),所以我应该在类定义上使用一个TModel泛型参数(就像我开始时那样),但是在后续的方法定义中忽略它。例如:

public class GridEditor<TModel> : where TModel : class
{
    public MvcHtmlString CheckBox<TValue>(Expression<Func<TModel, TValue>> expression)
    {
    }
}
公共类GridEditor:其中TModel:class
{
公共MvcHtmlString复选框(表达式)
{
}
}
在使用中(在razor中构建html表的foreach循环中),它如下所示:

@foreach (var pi in Model.Items)
{
    var ge = new GridEditor<AdamOneilSoftware.Models.ProfileItem>("/ServiceProfile/SaveItem", pi.ID);
    <tr>
    <td>@ge.CheckBox(x => x.AutoAdd)</td>
        <td>@ge.DropDownList(x => x.ItemID, ViewBag.ItemID as SelectList)</td>
        <td>@ge.TextBox(x => x.UnitPrice)</td>
        <td>@ge.Controls()</td>
    </tr>
}
@foreach(Model.Items中的var pi)
{
var ge=newgrideditor(“/ServiceProfile/SaveItem”,pi.ID);
@复选框(x=>x.AutoAdd)
@ge.DropDownList(x=>x.ItemID,ViewBag.ItemID作为SelectList)
@ge.TextBox(x=>x.UnitPrice)
@ge.Controls()
}