2009-11-30 3 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, но я понятия не имею, как отображать пользовательский код в моем методе визуализации.

Я пробовал использовать HtmlHelper без успеха. Я также попытался переопределить метод ToString, чтобы иметь возможность использовать синтаксис <%=Html.PanelWithHeader()..., но у меня остались синтаксические ошибки.

Как я могу это сделать?

ответ

0

Оказывается, что Telerik MVC extensions are open-source and available at CodePlex так что я взял быстрый взгляд на исходный код.

Они создают HtmlTextWriter из ViewContext экземпляра HtmlHelper. Когда они пишут, он записывает на страницу.

код становится:

// 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. –

Смежные вопросы