Come posso creare un controllo basato su modelli con Asp.Net MVC?
-
10-07-2019 - |
Domanda
Sto cercando di creare un controllo basato su modelli con Asp.Net MVC. Per controllo basato su modelli, intendo un controllo che accetta il markup come input in questo modo:
<% Html.PanelWithHeader()
.HeaderTitle("My Header")
.Content(() =>
{ %>
<!-- ul used for no particular reason -->
<ul>
<li>A sample</li>
<li>A second item</li>
</ul>
<% }).Render(); %>
Nota: Sì, è molto simile a come Telerik crea i suoi controlli MVC , mi piace la sintassi.
Ecco il mio codice 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();
}
}
Questo mostra il ul
, ma non ho idea di come visualizzare il codice personalizzato nel mio metodo Render.
Ho provato a utilizzare HtmlHelper senza successo. Ho anche provato a sovrascrivere il metodo ToString per poter utilizzare la sintassi <%=Html.PanelWithHeader()...
, ma ho continuato ad avere errori di sintassi.
Come posso farlo?
Soluzione 2
Si scopre che le le estensioni Telerik MVC sono open source e disponibili su CodePlex , quindi ho preso un rapida occhiata al codice sorgente.
Creano un HtmlTextWriter dal ViewContext dell'istanza HtmlHelper. Quando ci scrivono, scrive sulla pagina.
Il codice diventa:
// 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>");
}
}
* Lo so, il codice è un casino
Altri suggerimenti
public void Render()
{
Response.Write(getContentTemplateHandler());
}
Potresti voler fare qualcosa come Html.BeginPanel()
/ Html.EndPanel()
, simile a come vengono creati i moduli con Html.BeginForm()
/ Html.EndForm()
. In questo modo è possibile racchiudere il contenuto contenuto piuttosto che passarlo come parametro.