2012-11-15 9 views
13

Buduję stronę internetową za pomocą Twitter Bootstrap i ASP.Net C# Webforms. Mam ListView na mojej stronie z DataPager związany do niego, ale muszę zmienić sposób .Net renderuje HTML DataPager.Formatowanie asp: DataPager do pokazania w ul li

Obecnie wszystkie pozycje są wyświetlane pagera tak:

<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> 

jednak muszę zawijać wszystkie moje przedmioty w nieuporządkowanej liście zamiast rozpiętości oraz tagi. Mój obecny znak-up wygląda następująco:

<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> 

jakoś trzeba zastąpić NextPreviousPagerField i NumericPagerField więc oni wyjściowe <li> tagów zamiast <zakresowe> i < >.

+0

można dostarczyć css dodane tutaj w twoim kodzie. Właściwie to potrzebuję. –

Odpowiedz

14

Urządzenie DataPager nie obsługuje tego po wyjęciu z pudełka, więc będziesz potrzebować niestandardowego sterowania. Na szczęście jest dość na wschód, aby wdrożyć!

Dla każdego DataPagerField, DataPager dodaje kontrolkę DataPagerFieldItem do swojego własnego zbioru kontrolnego, a następnie informuje pole, aby utworzyło formanty w tym elemencie. Wbudowane pola dodadzą spacje nierozdzielające pomiędzy przyciskami (chyba że ustawisz właściwość RenderNonBreakingSpacesBetweenControls na false), ale są one dość łatwe do zidentyfikowania i zignorowania.

Kontrola ta będzie nadal uczynić <a> tagów dla włączonych przycisków i <span> tagu dla bieżącego numeru strony, ale powinien być zbliżony do tego, co trzeba: wyjście

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> 
+0

Dziękuję. W jaki sposób chciałbym użyć niestandardowego sterowania? – Arith

+1

W zależności od konfiguracji. W przypadku projektu strony internetowej najprostszym rozwiązaniem byłoby zapisanie kontroli w folderze 'App_Code', dodanie do strony dyrektywy' <% @ Register ...%> '(lub dodanie jej do pliku' system.web/strony/control' pliku 'web.config'), a następnie zamienić' asp: DataPager' na 'site: UnorderedListDataPager' na twojej stronie. –

+0

Dziękuję bardzo! Mam to teraz działa! :) – Arith

8

Oprócz odpowiedzi Richarda ... Użyłem jego podejścia i dodałem wsparcie dla klas "niepełnosprawnych" i "aktywnych" oraz okolicznych tagów div-Tag-

Aktualizacja: Dodałem sugestię Jana specjalnego renderowania aktywnego-Label jako hiperłącze do poprawnego renderowania stronicowania-SM i paginacji-LG. Tak więc kredyt i podziękowania dla Johna.

Aktualizacja 2: Dodano rendering dla id dla kontroli. Dzięki 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(); 
     } 
    } 
+0

To jest świetne. Po prostu krótką notatką dla każdego, kto używa metody 'AddAttributesToRender()', możesz chcieć dołączyć 'writer.AddAttribute (" id ", base.ClientID);' gdy stracisz wygenerowany element kontrolny 'id' podczas używania tej metody, która wydaje się zakłócać stronicowanie w pamięci (w przeciwieństwie do querystringu). – DGibbs

+0

Wielkie dzięki. Działało idealnie – samir105

1

Wprowadziłem dodatkowe zmiany w odpowiedzi Andreasa. Próbki Bootstrap zawijają bieżącą stronę (aktywną) wewnątrz znacznika hiperłącza, dlatego zauważyłem, że niektóre szablony Bootstrap nie formatują poprawnie aktywnego znacznika podczas wybierania zmiany rozmiaru, takiej jak pagination-lg lub pagination-sm. Oto moja wersja RenderContents z dodatkowym opakowaniem hiperłącza dodanym:

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(); 
       } 
      } 
     } 
    } 
8

Mam do tego nieco inne rozwiązanie.Zamiast zmieniać renderowanie DataPagera, nieznacznie zaadaptowałem znacznik, a pod względem renderowania nadal wygląda on jak "bootstrap-like", mimo że nie ma znaczników UL/LI z klasą stronicowania.

Bardzo ważna rzecz (jak wyjaśniono w https://stackoverflow.com/a/19398488/1948625) zmienia wyjściowe klasy asp.net dla wyłączonej kontroli, domyślnie jest to "aspNetDisabled", ale w przypadku bootstrap lepiej jest po prostu użyć "disabled". Zrób to w Application_Start w Global.asax. Jeśli nie, przyciski pierwszej strony, poprzedniej strony, następnej strony i ostatniej strony nie są wyłączone.

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

Źródło: WebControl.DisabledCssClass Property (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> 
powyżej

Asp.net serwer znaczników renderuje jak to pager: asp.net server markup renders as this pager

I to jest renderowane 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>