ASP.NET - сделать пользовательский CompositeControl для String? - PullRequest
0 голосов
/ 31 марта 2009

Я пытаюсь отобразить составной элемент управления в строку и записать его на страницу следующим образом:

Dim sb As New StringBuilder
Dim sw As New StringWriter(sb)
Dim hw As New HtmlTextWriter(sw)
Dim CustomCompositeControl as New MyCustomCompositeControl
CustomCompositeControl.RenderControl(hw)
HttpContext.Current.Response.Write(sb.ToString)

К сожалению, это просто рендеринг пустого тега span.

Можно ли даже преобразовать CompositeControls в строки, как, скажем, DataGrid?

Не вдаваясь в буквальные внутренности моего CompositeControl, есть ли что-то, во что я должен убедиться, внутри CompositeControl, прежде чем он будет визуализирован через RenderControl?

ПРИМЕЧАНИЕ. Я не перезаписываю RenderControl в моем CompositeControl. Мне нужно это сделать?

UPDATE Хорошо. Я как-то понял это. Я должен убедиться, что метод EnsureChildControls моего CompositeControl вызывается перед запуском метода RenderControl. Я просто не уверен насчет лучшего места для внутреннего вызова.

Ответы [ 3 ]

2 голосов
/ 31 марта 2009

Если у вас есть доступ к простому вызову метода Render (), просто сделайте это, и он даст вам искомый результат. В противном случае, да, вам придется переопределить RenderControl () ... в зависимости от того, когда вы его вызываете, вы можете обойтись простым вызовом метода Render () изнутри RenderControl ().

Кроме того, вы должны отметить, что html-тег верхнего уровня вашего составного элемента управления всегда будет span, если вы не укажете, что он является чем-то другим, например, div:

/// <summary>
/// Render as div instead of the default span.
/// </summary>
/// <value></value>
/// <returns>HtmlTextWriterTag.Div</returns>
protected override HtmlTextWriterTag TagKey
{
   get
   {
      return HtmlTextWriterTag.Div;
   }
}
1 голос
/ 31 марта 2009

Да, это возможно, но возможно ли это без понимания внутренних элементов управления и его зависимости от различных событий в жизненном цикле asp.net? Я не думаю, что это возможно.

DataGrid, вероятно, зависит от нахождения в форме, например, и я предполагаю, что это приведет к ошибке, указывающей на отсутствие формы.

0 голосов
/ 14 октября 2010

Взгляните на эту страницу MSDN, в которой обсуждаются CompositeControls , в частности, раздел под названием «Механизм рендеринга составных элементов управления»

обработка запросов код (в классе Page) звонки EnsureChildControls непосредственно перед запуск события PreRender на странице и каждый дочерний элемент управления.

Во время обычного запроса ASP.NET метод CreateChildControls (), который вы переопределяете в CompositeControl, не вызывается, пока не достигнет поздней стадии жизненного цикла запроса, прямо перед PreRender. Если вы пытаетесь визуализировать CompositeControl вне обычного жизненного цикла страницы ASP.NET, то дочерние элементы управления никогда не будут добавлены, потому что никогда не вызываются методы создания дочерних элементов управления. Лучший способ гарантировать, что EnsureChildControls () вызывается при ручной визуализации элемента управления, это переопределить RenderControl (), например, так:

public override void RenderControl(HtmlTextWriter writer)
{
    // We must explicitly call EnsureChildControls() in cases where we are rendering 
    // a CompositeControl outside of the normal ASP.NET page lifecycle
    EnsureChildControls();
    base.RenderControl(writer);
}

Мне кажется странным, что сам класс CompositeControl уже не переопределяет метод RenderControl () аналогичным образом. Если вы используете Reflector для изучения деталей реализации CompositeControl, вы увидите, что все методы, переопределенные в классе, сделаны исключительно для вызова EnsureChildControls (); даже Render () вызовет метод EnsureChildControls (), если элемент управления находится в режиме разработки. От отражателя:

protected internal override void Render(HtmlTextWriter writer)
{
    if (base.DesignMode)
    {
        this.EnsureChildControls();
    }
    base.Render(writer);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...