代码之家  ›  专栏  ›  技术社区  ›  mbillard

如何使用ASP.NET MVC创建模板化控件?

  •  1
  • mbillard  · 技术社区  · 14 年前

    我正在尝试用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 我喜欢句法。

    这是我的面板,标题代码:

    // 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 回复  |  直到 10 年前
        1
  •  0
  •   Jason    14 年前
    public void Render()
    {
        Response.Write(getContentTemplateHandler());
    }
    
        2
  •  0
  •   mbillard    14 年前

    事实证明, 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>");
        }
    }
    

    *我知道,密码一团糟

        3
  •  0
  •   Brian Mains    10 年前

    你可能想做点什么 Html.BeginPanel() / Html.EndPanel() ,类似于窗体的创建方式 Html.BeginForm() / Html.EndForm() . 这样就可以包装包含的内容,而不需要将其作为参数传递。