Arith Arith - 11 months ago 295
ASP.NET (C#) Question

Formatting an asp:DataPager to show in ul li

I am building a website using the Twitter Bootstrap and ASP.Net C# Webforms. I have a ListView on my page with a DataPager bound to it, but I need to change the way .Net renders the HTML of the DataPager.

Currently, all pager items are displaying like this:

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

however I need to wrap all my items in an unordered list rather than span and a tags.
My current mark-up looks like this:

<div class="clearfix pagination pagination-centered">
<asp:DataPager ID="dpListing" runat="server" PagedControlID="lvListing" PageSize="10" OnPreRender="dpListing_PreRender">
<asp:BulletedList ID="listPages" runat="server" DisplayMode="LinkButton" OnClick="listPages_Click"></asp:BulletedList>
<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" />

I somehow need to override the NextPreviousPagerField and NumericPagerField so they output <li> tags rather than <span> and <a>.

Answer Source

The DataPager doesn't support this out of the box, so you're going to need a custom control. Fortunately, it's quite east to implement!

For each DataPagerField, the DataPager adds a DataPagerFieldItem control to its own control collection, and then tells the field to create its controls within that item. The built-in fields will add non-breaking spaces between the buttons (unless you set the RenderNonBreakingSpacesBetweenControls property to false), but they're quite easy to identify and suppress.

This control will still render the <a> tags for the enabled buttons and the <span> tag for the current page number, but should be close to what you need:

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

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


HTML output:

<ul id="dpListing">
   <li><a class="aspNetDisabled">First</a></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>