2012-11-15 4 views
13

Ich baue eine Website mit dem Twitter Bootstrap und ASP.Net C# -Webformulare. Ich habe einen ListView auf meiner Seite, an den ein DataPager gebunden ist, aber ich muss den Weg ändern. Net rendert den HTML des DataPagers.Formatieren eines asp: DataPager zum Anzeigen in ul li

Derzeit werden alle Pager Elemente werden wie folgt dargestellt:

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

aber ich brauche alle meine Artikel in einer ungeordneten Liste wickeln, anstatt Spanne und a-Tags. Mein aktueller mark-up sieht wie folgt aus:

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

Ich muss irgendwie die NextPreviousPagerField und NumericPagerField außer Kraft setzen, so dass sie Ausgangs <li> Tags statt <Spanne> und <ein>.

+0

könnten Sie bieten Die CSS wurde hier in Ihrem Code hinzugefügt. Eigentlich brauche ich das. –

Antwort

14

Die DataPager unterstützt dies nicht, so dass Sie ein benutzerdefiniertes Steuerelement benötigen. Glücklicherweise ist es ziemlich ostwärts zu implementieren!

Für jedes DataPagerField fügt das DataPager ein Steuerelement DataPagerFieldItem seiner eigenen Steuerelementauflistung hinzu und weist dann das Feld an, seine Steuerelemente innerhalb dieses Elements zu erstellen. Die integrierten Felder fügen schussfreie Leerzeichen zwischen den Schaltflächen hinzu (außer Sie legen die RenderNonBreakingSpacesBetweenControls-Eigenschaft auf false fest), aber sie sind ziemlich einfach zu identifizieren und zu unterdrücken.

wird diese Kontrolle noch die <a> Tags für die aktivierten Tasten und der <span> Tag für die aktuelle Seitennummer machen, sollte aber in der Nähe sein, was Sie brauchen:

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

<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

Danke. Wie würde ich das benutzerdefinierte Steuerelement verwenden? – Arith

+1

Hängt von Ihrer Einrichtung ab. Für ein Website-Projekt wäre der einfachste Weg, das Steuerelement in Ihrem 'App_Code'-Ordner zu speichern, eine' <% @Registrieren ...%> '-Direktive zu Ihrer Seite hinzuzufügen (oder sie dem' system.web/hinzuzufügen). pages/controls 'Ihrer 'web.config' Datei), und ersetzen Sie dann den' asp: DataPager' durch 'site: UnorderedListDataPager' auf Ihrer Seite. –

+0

Vielen Dank! Ich habe das jetzt funktioniert! :) – Arith

8

Zusätzlich zu der Antwort von Richard ... Ich habe seinen Ansatz verwendet und zusätzliche Unterstützung für die "deaktivierten" und "aktiven" Klassen und die umliegenden div-Tag-

hinzugefügt

Update: Ich habe den Vorschlag von John für spezielle Wiedergabe des aktiven Zeichens als Hyperlink für die korrekte Wiedergabe von Paginierung-sm und Paginierung-lg. Also Kredit und Danke auch an John.

Update 2: Hinzugefügt Rendering von ID für die Kontrolle. Danke an 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

Das ist großartig. Nur eine kurze Notiz an alle, die '' AddAttributesToRender() 'Methode verwenden, möchten Sie' writer.AddAttribute ("id", base.ClientID) einschließen; 'wie Sie die generierte Kontrolle' id' verlieren, wenn Sie diese Methode verwenden, die erscheint interferieren mit dem In-Memory-Paging (im Gegensatz zu Querystring). – DGibbs

+0

Vielen Dank. Es hat perfekt funktioniert – samir105

1

Ich habe zusätzliche Änderungen an Andreas Antwort vorgenommen. Die Bootstrap-Beispiele umschließen die aktuelle Seite (aktive Seite) innerhalb eines Hyperlink-Tags. Daher habe ich festgestellt, dass einige Bootstrap-Vorlagen das aktive Tag nicht korrekt formatieren, wenn eine Größenvariation wie Paginierung-Lg oder Paginierung-SM gewählt wird. Hier ist meine Version von Render mit dem zusätzlichen Hyperlink Wrap hinzugefügt:

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

ich eine etwas andere Lösung dieses Problems haben.Anstatt das Rendering des DataPagers zu ändern, habe ich das Markup etwas angepasst und hinsichtlich des Renderings sieht es immer noch "Bootstrap-ähnlich" aus, obwohl es keine UL/LI-Tags mit Paginierungsklasse hat.

Eine sehr wichtige Sache (wie in https://stackoverflow.com/a/19398488/1948625 erklärt) ist das Ändern der Klasse asp.net Ausgaben für Behinderte Kontrolle, es standardmäßig "aspNetDisabled", aber für Bootstrap ist es viel besser, einfach "deaktiviert" zu verwenden. Tun Sie dies in Application_Start in der Global.asax. Wenn Sie dies nicht tun, werden die Schaltflächen für die erste Seite, die vorherige Seite, die nächste Seite und die letzte Seite nicht deaktiviert.

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

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

Asp.net Server-Markup macht oben als dieser Pager: asp.net server markup renders as this pager

Und das ist das gerenderte 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>