Como posso criar um controle modelo com Asp.Net MVC?
-
10-07-2019 - |
Pergunta
Eu estou tentando criar um controle modelo com Asp.Net MVC. Pelo controle modelo, quero dizer um controle que aceita marcação como entrada assim:
<% 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: Sim, isso é muito semelhante ao como Telerik cria seus controles MVC , eu como a sintaxe.
Aqui está o meu código 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();
}
}
Isto mostra a ul
, mas não tenho idéia de como exibir o código personalizado dentro do meu método de processamento.
Eu tentei usar o HtmlHelper sem sucesso. Eu também tentei substituir o método ToString para ser capaz de usar a sintaxe <%=Html.PanelWithHeader()...
, mas eu continuava a ter erros de sintaxe.
Como posso fazer isso?
Solução 2
Acontece que o extensões Telerik MVC são open-source e disponível em CodePlex isso, tomei um rápido olhar para o código-fonte.
Eles criam uma HtmlTextWriter do ViewContext da instância HtmlHelper. Quando eles escrevem para ele, ele escreve para a página.
O código torna-se:
// 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>");
}
}
* Eu sei, o código é uma bagunça
Outras dicas
public void Render()
{
Response.Write(getContentTemplateHandler());
}
Você pode querer fazer algo como Html.BeginPanel()
/ Html.EndPanel()
, semelhante à forma como as formas são criadas com Html.BeginForm()
/ Html.EndForm()
. Desta forma, você pode envolver o conteúdo contido em vez de necessidade de passá-lo como um parâmetro.