自定义ASP.NET MVC' RenderTable'帮手,如何添加一些额外的功能?

时间:2010-12-31 16:53:01

标签: c# asp.net-mvc asp.net-mvc-2 html-helper

所以我有一个我正在制作的自定义html助手,它会传递一个来自IList的表格。它运行良好,但它相当基本。我希望能够分配从属性名称中未推断的列名。例如,现在我传入一个名为 Number 的属性,但我想使用

我想我已经通过装饰看到了这一点,我只能假设它使用反射来获得价值,但我不太确定如何将它拉下来,但是......

另一件事,我想应用操纵细胞属性的能力。例如,单元格应该有colspan x ,或者任何其他单元格都可以应用class。我认为这也可能属于某种装饰。

最后,我想让一些单元格包含链接,但坦率地说,我不知道如何将它拉下来,而不是发送一个完整的html字符串作为要呈现的属性值。

所以,我在这里发布我当前版本的代码,希望有人比我更好(那将是你,;))可以给我一些关于如何完成什么的指示我上面写过。

更新

小更新,现在传入的IList是一个匿名类型,所以我不确定它是如何与装饰一起玩的......

public static class ApplicationExtensions {
    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        IList Items) {
        RenderTable(HtmlHelper, string.Empty, Items, null, false);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        IList Items,
        object Attributes) {
        RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        IList Items,
        IDictionary<string, object> Attributes) {
        RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        IList Items,
        object Attributes,
        bool RenderTFoot) {
        RenderTable(HtmlHelper, string.Empty, Items, Attributes.ToDictionary(), RenderTFoot);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        IList Items,
        IDictionary<string, object> Attributes,
        bool RenderTFoot) {
        RenderTable(HtmlHelper, string.Empty, Items, Attributes, RenderTFoot);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        string Caption,
        IList Items,
        object Attributes,
        bool RenderTFoot) {
        RenderTable(HtmlHelper, Caption, Items, Attributes.ToDictionary(), RenderTFoot);
    }

    public static void RenderTable(
        this HtmlHelper HtmlHelper,
        string Caption,
        IList Items,
        IDictionary<string, object> Attributes,
        bool RenderTFoot) {
        if ((Items != null) && (Items.Count > 0)) {
            StringBuilder TableBuilder = (String.IsNullOrEmpty(Caption) ? new StringBuilder() : new StringBuilder().AppendFormat("<caption>{0}</caption>", Caption));

            THead(TableBuilder, Items[0].GetType());
            TBody(TableBuilder, Items);

            if (RenderTFoot) {
                TFoot(TableBuilder, Items[0].GetPropertyCount());
            };

            TagBuilder TagBuilder = new TagBuilder("table");

            TagBuilder.MergeAttributes(Attributes);
            TagBuilder.InnerHtml = TableBuilder.ToString();

            HtmlHelper.ViewContext.HttpContext.Response.Write(TagBuilder.ToString(TagRenderMode.Normal));
        };
    }

    private static void THead(
        StringBuilder TableBuilder,
        Type Item) {
        TableBuilder.Append("<thead><tr>");

        foreach (var Property in Item.GetProperties()) {
            TableBuilder.AppendFormat("<th>{0}</th>", Property.Name);
        };

        TableBuilder.Append("</tr></thead>");
    }

    private static void TBody(
        StringBuilder TableBuilder,
        IList Items) {
        TableBuilder.Append("<tbody>");

        foreach (var Item in Items) {
            PropertyInfo[] Properties = Item.GetType().GetProperties();

            TableBuilder.Append("<tr>");

            foreach (PropertyInfo Property in Properties) {
                TableBuilder.AppendFormat("<td>{0}</td>", Property.GetValue(Item, null));
            };

            TableBuilder.Append("</tr>");
        };

        TableBuilder.Append("</tbody>");
    }

    private static void TFoot(
        StringBuilder TableBuilder,
        int Columns) {
        TableBuilder.AppendFormat("<tfoot><tr><td colspan=\"{0}\"><input type=\"button\" value=\"&#9664;\" /><input type=\"button\" value=\"&#9654;\" /></td></tr></tfoot>", Columns);
    }

    private static int GetPropertyCount(
        this object Item) {
        return Item.GetType().GetProperties().Count();
    }

    private static IDictionary<string, object> ToDictionary(
        this object Object) {
        return Object.GetType().GetProperties().ToDictionary(
            k =>
                (k.Name),
            v =>
                (v.GetValue(Object, null)));
    }
}

它的使用方式如下:

<% Html.RenderTable(Model) // lowest overload... %>

2 个答案:

答案 0 :(得分:0)

您可能希望查看Html.Grid中的ASP.NET MVC 3 RC2。它应该比编写自己的助手容易得多。

答案 1 :(得分:0)

“所以我不确定装饰品是如何起作用的......”

没有。您将无法从匿名中获取元数据。