dbones
dbones

Reputation: 4504

MVC Razor how can i use my HTML helper?

I have created a simple Gallery html helper, its not pretty at the moment, as I cannot get it work with Razor. (I would have liked to use Action as I would have done with the webforms viewengine)

public static HelperResult Gallery<T>(this HtmlHelper html,
                                IEnumerable<T> items,
                                int itemsPerRow,
                                Action rowContainer,
                                Func<T, HelperResult> itemContainer,
                                Action endRowContainer)
{
    if (items == null)
        return new HelperResult(writer => { });

    int itemCount = 1;

    return new HelperResult(writer =>
        {
            rowContainer();
            foreach (var item in items)
            {
                if (itemCount % itemsPerRow == 0)
                {
                    endRowContainer();
                    rowContainer();
                }
                itemContainer(item).WriteTo(writer);
                itemCount++;
            }
            endRowContainer();
        });


}

this is the intened usage, but the rowContainer and endRowContainer are outputed at the top of the generated HTML

@Html.Gallery(
        Model.Stores,
        3,
        ()=> { Response.Write("<div class=\"portfolio_box_container\">"); },
        @<div class="portfolio_box" style="padding-right: 25px">
            <img src="item.png" width="120" height="43" alt="" />
        </div>
        ,
        () => { Response.Write("</div>"); })

What im i doing wrong?

if should print off something like:

<div class="portfolio_box_container">
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
</div>
<div class="portfolio_box_container">
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
    <div class="portfolio_box" style="padding-right: 25px">
        <img src="item.png" width="120" height="43" alt="" />
    </div>
</div>

Upvotes: 0

Views: 463

Answers (1)

Tz_
Tz_

Reputation: 2949

The problem is that you should use the "writer" parameter of the HelperResult action to write the output in your actions to. Now you use Response.Write that immediately writes to the HTTP response, while the HelperResult has its own writer that will be copied to the response afterward.

The easiest solution is if you use an Action<TextWriter> instead of Action, and then you can pass on the "writer" to your action parts. E.g. use a parameter Action<TextWriter> rowContainer, and call it as rowContainer(writer) in the Gallery helper.

Then you can pass such an action parameter like (writer)=> { writer.Write("<div class=\"portfolio_box_container\">"); }

Upvotes: 2

Related Questions