如何使用Asp.Net MVC创建模板化控件?

时间:2009-11-30 20:42:17

标签: asp.net-mvc html-helper

我正在尝试使用Asp.Net MVC创建模板化控件。通过模板控制,我的意思是一个接受标记作为输入的控件,如下所示:

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

注意:是的,这与how Telerik creates its MVC controls非常相似,我喜欢语法。

这是我的PanelWithHeader代码:

// 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();
    }
}

这会显示ul,但我不知道如何在我的渲染方法中显示自定义代码。

我尝试过使用HtmlHelper但没有成功。我也尝试重写ToString方法以便能够使用<%=Html.PanelWithHeader()...语法,但我一直有语法错误。

我该怎么做?

3 个答案:

答案 0 :(得分:0)

您可能希望执行Html.BeginPanel() / Html.EndPanel()之类的操作,类似于使用Html.BeginForm() / Html.EndForm()创建表单的方式。这样您就可以包含所包含的内容,而不需要将其作为参数传递。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

事实证明Telerik MVC extensions are open-source and available at CodePlex所以我快速查看了源代码。

他们从HtmlHelper实例的ViewContext创建一个HtmlTextWriter。当他们写信给它时,它会写入页面。

代码变为:

// 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>");
    }
}

*我知道,代码很乱