none
Переопределить теги рендера system.web.ui.updatepanel RRS feed

  • Вопрос

  • Добрый день!

    Подскажите пожалуйста, можно ли и как переопределить теги html в которые рендерится Updatepanel? Сейчас это происходит в DIV, необходимо в Table. Выслушаю все методы вплоть до патчинга системных библиотек.

    VS 2008/2010/2012, ASP.NET

Ответы

  • Собственно немного текста для тех кто захочет заморочиться:

    пользуясь этой ссылкой создаем класс наследующийся от UpdatePanel:

    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    
    namespace DipComponents
    {
    	
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:DipUpdatePanel runat=server></{0}:DipUpdatePanel>")]
    
        public class DipUpdatePanel : System.Web.UI.UpdatePanel, INamingContainer
        {
    
    
            protected override void RenderChildren(HtmlTextWriter writer)
            {
    
                if (IsInPartialRendering)
                {
                    base.RenderChildren(writer);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "up");
                    writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
                    writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
                    writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                    writer.RenderBeginTag("table");
                    foreach (Control child in Controls)
                    {
                        child.RenderControl(writer);
                    }
                    writer.RenderEndTag();
                }
            }
    
        }
    
    
    
    }

    Компилируем его в библиотеку, примерно так:

    csc.exe /t:library /r:System.Web.dll DipComponents.cs

    библиотеку (в моем случе это получится DipComponents.dll) подключаем к reference проекта и в *.aspx страницы регистрируем:

    <%@ Register assembly="DipComponents" namespace="DipComponents" tagprefix="dip" %>

    ну и дальше в этой же странице используем как

    <dip:DipUpdatePanel ID="UpdatePanelContent" runat="server" UpdateMode="Conditional"><ContentTemplate> ... тра-ля-ля

    (однако следует учитывать, что в моем примере заменяется лишь тег таблицы, строки и ячейки нужно прописать руками уже самому внутри панели). Компилирование в dll сделано для исключения циклических ссылок, которые скорее всего вылезут при использовании *.cs с классом в проекте.

Все ответы

  • Что мешает использовать таблицу внутри update panel?
  • Можно попытаться использовать такие костыли, но это всё равно не то. А вот что предложили высше - самое то.
    Модератор
  • У Update panel есть свойство RenderMode которое может принимать 2 значения Inline и Block, первое соответствует тэгу <span> второе <div>. Если вы всетаки решили использовать table то можете, как предложил Yatajga переопределить метод RenderChildren. Но смысла я в этом не вижу.

            protected override void RenderChildren(HtmlTextWriter writer)
            {
                writer.AddAttribute("ID", ClientID);
                writer.RenderBeginTag("table");
                foreach (Control child in Controls)
                {
                    child.RenderControl(writer);
                }
                writer.RenderEndTag();
            }

  • Вот только я не могу понять какой смысл использовать таблицу, что это Вам даст? Не вижу никакого практического смысла.
    Модератор
  • Таблица внутри <div> не сможет растянуть его по вертикали будучи заданной высотой в 100%. А DIV до сих пор везде не умеет корректно растягиваться по высоте родителя (у родителя, разумеется, не указаны абсолютные значения) кроме как в браузере ИЕ (что довольно странно, хоть тут он впереди всех :) ). Соответственно панель с контентом который должен быть на 100% по высоте родителя ренредится в DIV, а див не растягивается, и получается таблица внутри сжатого дива.
  • Спасибо, попробую и отпишусь
  • Табличная верстка - это "железный" каркас с минимумом костылей и извращений. Таблица легким движением руки растянется по высоте на 100%, верстка простая и без особых "граблей"
  • Да, проблемы вёрстки такие. Поэтому приходится идти на всякие ухищрения. Но не надо смешивать программную часть и вёрстку. Лучше делать хаки в вёрстке, чем в коде. Можно в конце концов поместить div в таблицу, а в него ещё одну таблицу. Я не ас в вёрстке, но думаю , что можно будет решить вашу проблему не прибегая к костылям в серверном коде.
    Модератор
  • Ничего хакнуть со стороны верстки нельзя, испробовано и потрачено много времени и нервов. Да и что это за костыли? Нужно устранять причину, а не исправлять ее последствия, в моем случае это DIV вставляемый панелью в мою табличную верстку.
  • "Ничего хакнуть со стороны верстки нельзя, испробовано и потрачено много времени и нервов." - а как же JavaScript. Всё что нельзя через CSS можно через JS.  Сейчас div - ами верстают всё, таблицы уже в прошлом."Да и что это за костыли?" - хардкод. Ещё, если что насчёт вашей вёрстки можете спросить и тут. Если всё же хотите использовать UpdatePanel и серверный код, то можете посмотреть решение ссылку на которую дал высше.
    Модератор
  • "Ничего хакнуть со стороны верстки нельзя, испробовано и потрачено много времени и нервов." - а как же JavaScript. Всё что нельзя через CSS можно через JS.  Сейчас div - ами верстают всё, таблицы уже в прошлом."Да и что это за костыли?" - хардкод. Ещё, если что насчёт вашей вёрстки можете спросить и тут. Если всё же хотите использовать UpdatePanel и серверный код, то можете посмотреть решение ссылку на которую дал высше.

    Сейчас дивами верстают те, кто хочет проблем либо интересно делать костыли. Либо те кто делают "потому что модно". Некоторые люди которые тоже "как все" верстали дивами взглянув на мой шаблон сказали "это невозможно". Решение выше уже пытаюсь реализовать

  • Ясно, будут результаты, отпишитесь.
    Модератор
  • Ясно, будут результаты, отпишитесь.

    Переопределить получилось, но проблема теперь с AjaxControlToolkit, запросы он не парсит и JS вылетает с ошибкой "PageRequestManagerParserErrorException" даже если я переопределяю теги на div (т.е. в итоге получается исходный html)
  • В вашем случае думаю лучше будет делать ручные AJAX вызовы с использованием JQuery к методу веб-сервиса или Web API, который будет возвращать нужную разметку.
    Модератор
  • В вашем случае думаю лучше будет делать ручные AJAX вызовы с использованием JQuery к методу веб-сервиса или Web API, который будет возвращать нужную разметку.

    Проблему с парсингом победил, но вот innerHTML ну table не на всех браузерах есть :( а именно через него аякс вставляет данные :(

    PS вручную уже сложно что либо делать, проект большой

  • Собственно немного текста для тех кто захочет заморочиться:

    пользуясь этой ссылкой создаем класс наследующийся от UpdatePanel:

    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    
    namespace DipComponents
    {
    	
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:DipUpdatePanel runat=server></{0}:DipUpdatePanel>")]
    
        public class DipUpdatePanel : System.Web.UI.UpdatePanel, INamingContainer
        {
    
    
            protected override void RenderChildren(HtmlTextWriter writer)
            {
    
                if (IsInPartialRendering)
                {
                    base.RenderChildren(writer);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "up");
                    writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
                    writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
                    writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                    writer.RenderBeginTag("table");
                    foreach (Control child in Controls)
                    {
                        child.RenderControl(writer);
                    }
                    writer.RenderEndTag();
                }
            }
    
        }
    
    
    
    }

    Компилируем его в библиотеку, примерно так:

    csc.exe /t:library /r:System.Web.dll DipComponents.cs

    библиотеку (в моем случе это получится DipComponents.dll) подключаем к reference проекта и в *.aspx страницы регистрируем:

    <%@ Register assembly="DipComponents" namespace="DipComponents" tagprefix="dip" %>

    ну и дальше в этой же странице используем как

    <dip:DipUpdatePanel ID="UpdatePanelContent" runat="server" UpdateMode="Conditional"><ContentTemplate> ... тра-ля-ля

    (однако следует учитывать, что в моем примере заменяется лишь тег таблицы, строки и ячейки нужно прописать руками уже самому внутри панели). Компилирование в dll сделано для исключения циклических ссылок, которые скорее всего вылезут при использовании *.cs с классом в проекте.

  • Спасибо, что выложили полное решение проблемы. Оно в будущем может пригодится всем тем, кто столкнётся с подобным.
    Модератор