Подтвердить что ты не робот

Форматирование asp: DataPager для отображения в ul li

Я создаю веб-сайт, используя Twitter Bootstrap и ASP.Net С# Webforms. У меня есть ListView на моей странице с привязкой DataPager, но мне нужно изменить способ .Net отображает HTML файл DataPager.

В настоящее время все элементы пейджера отображаются следующим образом:

<div class="clearfix pagination pagination-centered"> <span id="cpBody_dpListing"> <a class="aspNetDisabled">First</a>&nbsp;<span>1</span>&nbsp; <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl02$ctl01','')">2</a>&nbsp; <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl03$ctl00','')">Last</a>&nbsp; </span> </div>

однако мне нужно обернуть все мои объекты в неупорядоченный список, а не span и теги. Моя текущая надпись выглядит следующим образом:

<div class="clearfix pagination pagination-centered">
<asp:DataPager ID="dpListing" runat="server" PagedControlID="lvListing" PageSize="10" OnPreRender="dpListing_PreRender">
    <Fields>
        <asp:TemplatePagerField>
            <PagerTemplate>
                <asp:BulletedList ID="listPages" runat="server" DisplayMode="LinkButton" OnClick="listPages_Click"></asp:BulletedList>
            </PagerTemplate>
        </asp:TemplatePagerField>
        <asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" />
        <asp:NumericPagerField PreviousPageText="&lt; Prev 10" NextPageText="Next 10 &gt;" ButtonCount="10" />
        <asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" />
    </Fields>
</asp:DataPager>

Мне почему-то нужно переопределить NextPreviousPagerField и NumericPagerField, чтобы они выводили <li> теги, а не <span> и <a> .

4b9b3361

Ответ 1

DataPager не поддерживает это из коробки, поэтому вам понадобится настраиваемый элемент управления. К счастью, он довольно восточный, чтобы реализовать!

Для каждого DataPagerField, DataPager добавляет элемент управления DataPagerFieldItem в свою собственную коллекцию управления, а затем указывает этому полю создавать свои элементы управления внутри этого элемента. Встроенные поля будут добавлять неразрывные пробелы между кнопками (если вы не установите для свойства RenderNonBreakingSpacesBetweenControls значение false), но их довольно легко определить и подавить.

Этот элемент по-прежнему будет отображать теги <a> для активированных кнопок и тег <span> для текущего номера страницы, но должен быть близок к тому, что вам нужно:

public class UnorderedListDataPager : DataPager
{
   protected override HtmlTextWriterTag TagKey 
   {
      get { return HtmlTextWriterTag.Ul; }
   }

   protected override void RenderContents(HtmlTextWriter writer)
   {
      if (HasControls())
      {
         foreach (Control child in Controls)
         {
            var item = child as DataPagerFieldItem;
            if (item == null || !item.HasControls())
            {
                child.RenderControl(writer);
                continue;
            }

            foreach (Control button in item.Controls)
            {
               var space = button as LiteralControl;
               if (space != null && space.Text == "&nbsp;") continue;

               writer.RenderBeginTag(HtmlTextWriterTag.Li);
               button.RenderControl(writer);
               writer.RenderEndTag();
            }
         }
      }
   }
}

Выход HTML:

<ul id="dpListing">
   <li><a class="aspNetDisabled">First</a></li>
   <li><span>1</span></li>
   <li><a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl02$ctl01','')">2</a></li>
   <li><a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl03$ctl00','')">Last</a></li>
</ul>

Ответ 2

В дополнение к ответу Ричарда... Я использовал его подход и добавил поддержку "отключенных" и "активных" классов и окружающего div-Tag -

Обновление: Я добавил предложение Джона для специального рендеринга active-Label как гиперссылки для правильного отображения pagination-sm и pagination-lg. Так что кредит и спасибо Джону тоже.

Обновление 2: Добавлен рендеринг id для элемента управления. Благодаря DGibbs.

    [
    Bindable(false),
    Category("Appearance"),
    DefaultValue("pagination pagination-centered"),
    Description("Css class for the surrounding div")
    ]
    public virtual string CssClass {
        get {
            if (ViewState["CssClass"] == null) {
                ViewState["CssClass"] = "pagination pagination-centered";
            }
            return (string)ViewState["CssClass"];
        }
        set {
            ViewState["CssClass"] = value;
        }
    }

    protected override HtmlTextWriterTag TagKey {
        get {
                return HtmlTextWriterTag.Div;
        }
    }

    protected override void AddAttributesToRender(HtmlTextWriter writer) {
            if (HasControls()) {
                writer.AddAttribute("id", base.ClientID);
                writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
            }
    }

    protected override void RenderContents(HtmlTextWriter writer) {
        if (HasControls()) {
            writer.RenderBeginTag(HtmlTextWriterTag.Ul);

            foreach (Control child in Controls) {
                var item = child as DataPagerFieldItem;
                if (item == null || !item.HasControls()) {
                    child.RenderControl(writer);
                    continue;
                }

                foreach (Control ctrl in item.Controls) {
                    var space = ctrl as LiteralControl;
                    if (space != null && space.Text == "&nbsp;")
                        continue;

                    // Set specific classes for li-Tag
                    bool isCurrentPage = false
                    if (ctrl is System.Web.UI.WebControls.WebControl) {
                        // Enabled = false -> "disabled"
                        if (!((System.Web.UI.WebControls.WebControl)ctrl).Enabled) {
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "disabled");
                        }

                        // there can only be one Label in the datapager -> "active"
                        if (ctrl is System.Web.UI.WebControls.Label) {
                           isCurrentPage = true;                     
                           writer.AddAttribute(HtmlTextWriterAttribute.Class, "active");
                        }
                    }
                    writer.RenderBeginTag(HtmlTextWriterTag.Li);
                    // special rendering as hyperlink for current page
                    if (isCurrentPage) {
                        writer.AddAttribute(HtmlTextWriterAttribute.Href, "#");
                        writer.RenderBeginTag(HtmlTextWriterTag.A);
                    }
                    ctrl.RenderControl(writer);
                    if (isCurrentPage) {
                        writer.RenderEndTag(); // A
                    }
                    writer.RenderEndTag();
                }
            }

            writer.RenderEndTag();
        }
   }

Ответ 3

У меня есть немного другое решение. Вместо изменения рендеринга DataPager я немного адаптировал разметку, и с точки зрения рендеринга он по-прежнему выглядит как "bootstrap-like", хотя он не имеет тегов UL/LI с классом разбиения на страницы.

Очень важная вещь (как описано в fooobar.com/questions/367706/...) меняет выходы класса asp.net класса для отключенного управления, по умолчанию используется "aspNetDisabled", но для начальной загрузки гораздо лучше просто использовать "отключен". Сделайте это в Application_Start в Global.asax. Если вы этого не сделаете, кнопки первой страницы, предыдущей страницы, следующей страницы и последней страницы не будут отключены.

void Application_Start(object sender, EventArgs e)
{
    WebControl.DisabledCssClass = "customDisabledClassName";
}

Источник: Свойство WebControl.DisabledCssClass(MSDN)

    <asp:DataPager ID="it" runat="server" class="btn-group btn-group-sm">
        <Fields>
            <asp:NextPreviousPagerField PreviousPageText="<" FirstPageText="|<" ShowPreviousPageButton="true"
                ShowFirstPageButton="true" ShowNextPageButton="false" ShowLastPageButton="false"
                ButtonCssClass="btn btn-default" RenderNonBreakingSpacesBetweenControls="false" RenderDisabledButtonsAsLabels="false" />
            <asp:NumericPagerField ButtonType="Link" CurrentPageLabelCssClass="btn btn-primary disabled"  RenderNonBreakingSpacesBetweenControls="false"
                NumericButtonCssClass="btn btn-default" ButtonCount="10" NextPageText="..." NextPreviousButtonCssClass="btn btn-default" />
            <asp:NextPreviousPagerField NextPageText=">" LastPageText=">|" ShowNextPageButton="true"
                ShowLastPageButton="true" ShowPreviousPageButton="false" ShowFirstPageButton="false"
                ButtonCssClass="btn btn-default" RenderNonBreakingSpacesBetweenControls="false" RenderDisabledButtonsAsLabels="false"/>
        </Fields>
    </asp:DataPager>

Разметка сервера Asp.net выше отображается как этот пейджер: asp.net server markup renders as this pager

И это рендер html:

<span id="ctl00_Body_CaseList918421504_ListControl_Pager_it" class="btn-group btn-group-sm">
    <a class="disabled btn btn-default">|&lt;</a>
    <a class="disabled btn btn-default">&lt;</a>
    <span class="btn btn-primary disabled">1</span>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl01','')">2</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl02','')">3</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl03','')">4</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl04','')">5</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl05','')">6</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl06','')">7</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl07','')">8</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl08','')">9</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl09','')">10</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl01$ctl10','')">...</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl02$ctl00','')">&gt;</a>
    <a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl02$ctl01','')">&gt;|</a>
</span>

Ответ 4

Я внесла дополнительные изменения в ответ Андреаса. Образцы Bootstrap обертывают текущую страницу (активную) внутри тега гиперссылки, поэтому я заметил, что некоторые шаблоны Bootstrap не форматируют активный тег правильно при выборе такого размера, как pagination-lg или pagination-sm. Вот моя версия RenderContents с добавлением дополнительной гиперссылки:

    protected override void RenderContents(HtmlTextWriter writer)
    {
        if (HasControls())
        {
            foreach (Control child in Controls)
            {
                var item = child as DataPagerFieldItem;
                if (item == null || !item.HasControls())
                {
                    child.RenderControl(writer);
                    continue;
                }

                foreach (Control ctrl in item.Controls)
                {
                    var space = ctrl as LiteralControl;
                    if (space != null && space.Text == "&nbsp;")
                        continue;

                    // Set specific classes for li-Tag
                    var isCurrentPage = false;
                    if (ctrl is WebControl)
                    {
                        // Enabled = false -> "disabled"
                        if (!((WebControl)ctrl).Enabled)
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "disabled");

                        // there can only be one Label in the datapager -> "active"
                        if (ctrl is Label)
                        {
                            isCurrentPage = true;
                            writer.AddAttribute(HtmlTextWriterAttribute.Class, "active");
                        }
                    }

                    writer.RenderBeginTag(HtmlTextWriterTag.Li);
                    if (isCurrentPage)
                    {
                        writer.AddAttribute(HtmlTextWriterAttribute.Href, "#");
                        writer.RenderBeginTag(HtmlTextWriterTag.A);
                    }
                    ctrl.RenderControl(writer);
                    if (isCurrentPage)
                        writer.RenderEndTag();
                    writer.RenderEndTag();
                }
            }
        }
    }