2009-11-30 5 views
1

J'essaye de créer un contrôle basé sur un modèle avec Asp.Net MVC. Par le contrôle basé sur un modèle, je veux dire un contrôle qui accepte le balisage en entrée comme ceci:Comment puis-je créer un contrôle basé sur un modèle avec 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(); %> 

Note: Oui, ce qui est très similaire à how Telerik creates its MVC controls, j'aime la syntaxe.

Voici mon code 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(); 
    } 
} 

Cette affiche le ul, mais je ne sais pas comment afficher un code personnalisé au sein de ma méthode de rendu.

J'ai essayé d'utiliser le HtmlHelper sans succès. J'ai également essayé de remplacer la méthode ToString pour pouvoir utiliser la syntaxe <%=Html.PanelWithHeader()..., mais j'ai continué à avoir des erreurs de syntaxe.

Comment est-ce que je peux faire ceci?

Répondre

0

Il se trouve que le Telerik MVC extensions are open-source and available at CodePlex donc je pris un coup d'œil au code source.

Ils créent un HtmlTextWriter à partir du ViewContext de l'instance HtmlHelper. Quand ils lui écrivent, il écrit à la page.

Le code devient:

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

* Je sais, le code est un gâchis

0

Vous voudrez peut-être faire quelque chose comme Html.BeginPanel()/Html.EndPanel(), similaire à la façon dont les formulaires sont créés avec Html.BeginForm()/Html.EndForm(). De cette façon, vous pouvez envelopper le contenu contenu plutôt que de le passer en paramètre.

+0

Cela fonctionnerait, mais son laid et demande à l'utilisateur de se rappeler d'appeler les deux. – mbillard

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

Le point étant que, pour obtenir la sortie d'un '<% %>' sans un signe égal, vous devez écrire dans l'objet Response. –

Questions connexes