Как я могу создать шаблонный элемент управления с Asp.Net MVC?
-
10-07-2019 - |
Вопрос
Я пытаюсь создать шаблонный элемент управления с помощью 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(); %>
Примечание. Да, это очень похоже на то, как Telerik создает свои элементы управления MVC Мне нравится синтаксис.
Вот мой код 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()...
, но у меня по-прежнему были синтаксические ошибки.
Как я могу это сделать?
Решение 2
Оказывается, что расширения Telerik MVC имеют открытый исходный код и доступны в 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>");
}
}
* Я знаю, код это беспорядок
Другие советы
public void Render()
{
Response.Write(getContentTemplateHandler());
}
Возможно, вы захотите сделать что-то вроде Html.BeginPanel()
/ Html.EndPanel()
, аналогично тому, как формы создаются с помощью Html.BeginForm()
/ Html.EndForm()
. Таким образом, вы можете обернуть содержимое, а не передавать его в качестве параметра.