2009-11-30 34 views
1

我試圖用Asp.Net MVC創建一個模板化的控件。通過模板控制,我的意思是接受標記作爲輸入,像這樣控制:如何使用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,但我不知道如何顯示我的Render方法中的自定義代碼。

我試過使用HtmlHelper沒有成功。我也嘗試覆蓋ToString方法,以便能夠使用<%=Html.PanelWithHeader()...語法,但我一直有語法錯誤。

我怎樣才能做到這一點?

回答

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

*我知道,代碼是一個爛攤子

0

你可能想要做像Html.BeginPanel()/Html.EndPanel(),類似形式如何與Html.BeginForm()/Html.EndForm()創建。這樣你可以包裝包含的內容,而不需要將它作爲參數傳遞。

+0

這會工作,但它的醜陋,要求用戶記住調用兩者。 – mbillard

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

問題的關鍵在於,爲了從不帶等號的'<% %>'輸出,必須寫入Response對象。 –

相關問題