开发者

Custom ASP.NET MVC 'RenderTable' helper, how to add some extra functionality?

so I have a custom html helper I'm making and it renders a table from an IList that's passed in. It works fine, but its rather basic. I'd like to have the ability to assign column names that are not inferred from the property name. For example, right now I pass in a property called Number, but I'd like to use .

I think I've seen this done through decorations, and I can only assume it uses reflection to get the value out, but I'm not quite sure how to pull it off, yet...

Another thing, I'd like to apply the ability to manipulate the attributes of a cell. For example the cell should have a colspan of x, or any other cell could have a class applied to it. I'm thinking that could also fall under a decoration of some kind.

Lastly, I want to have some cells contain links, but quite frankly, I have no idea how to pull it off, short of sending a complete html string as the property value to render.

So, I'm posting my current version of the code here with the hope that someone better than me (that would be you, ;)) could give me some pointers on how to accomplish what I've written above.

UPDATE

Small update, the IList being passed in right now is an anonymous type, so I'm not sure how that plays with decorations...

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开发者_JS百科,
        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)));
    }
}

And it's used like so:

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


You might want to have a look at Html.Grid from ASP.NET MVC 3 RC2. It should be much easier than writing your own helper.


" so I'm not sure how that plays with decorations..."

It doesn't. You won't be able to get metadata off of an anon.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜