twitter-bootstrap 格式化 asp:DataPager 以在 ul li 中显示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13394686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 15:43:41  来源:igfitidea点击:

Formatting an asp:DataPager to show in ul li

c#asp.nettwitter-bootstrapdatapager

提问by Arith

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.

我正在使用 Twitter Bootstrap 和 ASP.Net C# Webforms 构建一个网站。我的页面上有一个 ListView,绑定了 DataPager,但我需要更改 .Net 呈现 DataPager 的 HTML 的方式。

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

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

我不知何故需要覆盖 NextPreviousPagerField 和 NumericPagerField,以便它们输出 <li> 标签而不是 <span> 和 <a>。

回答by Richard Deeming

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

DataPager不支持此开箱即用,所以你会需要一个自定义的控制。幸运的是,它实施起来相当东方!

For each DataPagerField, the DataPageradds a DataPagerFieldItemcontrol 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 RenderNonBreakingSpacesBetweenControlsproperty to false), but they're quite easy to identify and suppress.

对于每个DataPagerFieldDataPager将一个DataPagerFieldItem控件添加到它自己的控件集合中,然后告诉该字段在该项目中创建它的控件。内置字段将在按钮之间添加不间断空格(除非您将RenderNonBreakingSpacesBetweenControls属性设置为false),但它们很容易识别和抑制。

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:

此控件仍将呈现已<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 output:

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>

回答by Thierry_S

I have a slightly different solution to this. Instead of changing the rendering of the DataPager, I have slightly adapted the markup, and in terms of rendering, it still looks "bootstrap-like", even though it doesn't have the UL/LI tags with pagination class.

我对此有一个稍微不同的解决方案。我没有改变 DataPager 的渲染,而是稍微调整了标记,在渲染方面,它看起来仍然“类似引导程序”,即使它没有带有分页类的 UL/LI 标签。

A very important thing (as explained in https://stackoverflow.com/a/19398488/1948625) is changing the class asp.net outputs for disabled control, it defaults to "aspNetDisabled" but for bootstrap it's much better to simply use "disabled". Do this in Application_Start in the Global.asax. If you don't, the first page, previous page, next page and last page buttons don't appear disabled.

一件非常重要的事情(如https://stackoverflow.com/a/19398488/1948625 中所述)正在更改类 asp.net 输出以禁用控制,它默认为“aspNetDisabled”,但对于引导程序,简单地使用“残疾”。在 Global.asax 的 Application_Start 中执行此操作。如果不这样做,则第一页、上一页、下一页和最后一页按钮不会显示为禁用。

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

Source: WebControl.DisabledCssClass Property (MSDN)

来源: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 server markup above renders as this pager: asp.net server markup renders as this pager

上面的 Asp.net 服务器标记呈现为这个寻呼机: asp.net 服务器标记呈现为此寻呼机

And this is the rendered html:

这是呈现的 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>

回答by Andreas Krohn

In addition to the answer of Richard ... I used his approach and added support for the "disabled" and "active" classes and the surrounding div-Tag-

除了理查德的回答......我使用了他的方法并添加了对“禁用”和“活动”类以及周围 div-Tag- 的支持

Update:I added the suggestion of John for special rendering of the active-Label as a hyperlink for correct rendering of pagination-smand pagination-lg. So credit and thanks to John too.

更新:我添加了 John 对 active-Label 的特殊渲染的建议,作为正确渲染pagination-smpagination-lg的超链接。所以也感谢约翰。

Update 2:Added rendering of idfor the control. Thanks to DGibbs.

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

回答by John

I've made additional changes to Andreas's answer. The Bootstrap samples wrap the current page (active) page inside of a hyperlink tag, so I've noticed that some Bootstrap templates do not format the active tag correctly when choosing a size variation such as pagination-lg or pagination-sm. Here is my version of RenderContents with the extra hyperlink wrap added:

我对 Andreas 的回答做了额外的修改。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();
                }
            }
        }
    }