How can I create a templated control with Asp.Net MVC?

送分小仙女□ 提交于 2019-12-11 06:11:35

问题


I'm trying to create a templated control with Asp.Net MVC. By templated control, I mean a control that accepts markup as input like so:

<% Html.PanelWithHeader()
    .HeaderTitle("My Header")
    .Content(() =>
    { %>
        <!-- ul used for no particular reason -->
        <ul>
          <li>A sample</li>
          <li>A second item</li>
        </ul>
    <% }).Render(); %>

Note: Yes, this is very similar to how Telerik creates its MVC controls, I like the syntax.

Here's my PanelWithHeader code:

// Extend the HtmlHelper
public static PanelWithHeaderControl PanelWithHeader(this HtmlHelper helper)
{
    return new PanelWithHeaderControl();
}

public class PanelWithHeaderControl
{
    private string headerTitle;

    private Action getContentTemplateHandler;

    public PanelWithHeaderControl HeaderTitle(string headerTitle)
    {
        this.headerTitle = headerTitle;

        return this;
    }

    public PanelWithHeaderControl Content(Action getContentTemplateHandler)
    {
        this.getContentTemplateHandler = getContentTemplateHandler;

        return this;
    }

    public void Render()
    {
        // display headerTitle as <div class="header">headerTitle</div>

        getContentTemplateHandler();
    }
}

This displays the ul, but I have no idea how to display custom code within my Render method.

I have tried using the HtmlHelper with no success. I have also tried overriding the ToString method to be able to use the <%=Html.PanelWithHeader()... syntax, but I kept having syntax errors.

How can I do this?


回答1:


public void Render()
{
    Response.Write(getContentTemplateHandler());
}



回答2:


It turns out that the Telerik MVC extensions are open-source and available at CodePlex so I took a quick look at the source code.

They create an HtmlTextWriter from the ViewContext of the HtmlHelper instance. When they write to it, it writes to the page.

The code becomes:

// Extend the HtmlHelper
public static PanelWithHeaderControl PanelWithHeader(this HtmlHelper helper)
{
    HtmlTextWriter writer = helper.ViewContext.HttpContext.Request.Browser.CreateHtmlTextWriter(helper.ViewContext.HttpContext.Response.Output);

    return new PanelWithHeaderControl(writer);
}

public class PanelWithHeaderControl
{
    private HtmlTextWriter writer;

    private string headerTitle;

    private Action getContentTemplateHandler;

    public PanelWithHeaderControl(HtmlTextWriter writer)
    {
        this.writer = writer;
    }

    public PanelWithHeaderControl HeaderTitle(string headerTitle)
    {
        this.headerTitle = headerTitle;

        return this;
    }

    public PanelWithHeaderControl Content(Action getContentTemplateHandler)
    {
        this.getContentTemplateHandler = getContentTemplateHandler;

        return this;
    }

    public void Render()
    {
        writer.Write("<div class=\"panel-with-header\"><div class=\"header\">" + headerTitle + "</div><div class=\"content-template\">");

        getContentTemplateHandler();

        writer.Write("</div></div>");
    }
}

*I know, the code is a mess




回答3:


You might want to do something like Html.BeginPanel() / Html.EndPanel(), similar to how forms are created with Html.BeginForm() / Html.EndForm(). This way you can wrap the contained content rather than need to pass it as a parameter.



来源:https://stackoverflow.com/questions/1822272/how-can-i-create-a-templated-control-with-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!