我正在使用Twitter Bootstrap和ASP.Net C#Webforms构建一个网站。我的页面上有一个ListView,其中绑定了DataPager,但我需要改变.Net呈现DataPager的HTML。
目前,所有寻呼机项目都显示如下:
<div class="clearfix pagination pagination-centered"> <span id="cpBody_dpListing"> <a class="aspNetDisabled">First</a> <span>1</span> <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl02$ctl01','')">2</a> <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl03$ctl00','')">Last</a> </span> </div>
但是我需要将所有项目包装在无序列表中,而不是跨度和标签。 我目前的加价看起来像这样:
<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="< Prev 10" NextPageText="Next 10 >" ButtonCount="10" />
<asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" />
</Fields>
</asp:DataPager>
我不知何故需要覆盖NextPreviousPagerField和NumericPagerField,以便输出&lt; li&gt;标签而不是&lt; span&gt;和&lt; a&gt;。
答案 0 :(得分:14)
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 == " ") 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>
答案 1 :(得分:9)
我对此有一个稍微不同的解决方案。我没有改变DataPager的渲染,而是略微调整了标记,在渲染方面,它仍然看起来像“类似引导程序”,即使它没有带分页类的UL / LI标记。
一个非常重要的事情(如https://stackoverflow.com/a/19398488/1948625中所述)是为禁用控件更改类asp.net输出,它默认为“aspNetDisabled”,但对于bootstrap,只需使用“disabled”就好了。在Global.asax的Application_Start中执行此操作。如果不这样做,则第一页,上一页,下一页和最后一页按钮不会显示为禁用。
void Application_Start(object sender, EventArgs e)
{
WebControl.DisabledCssClass = "customDisabledClassName";
}
来源: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服务器标记呈现为此寻呼机:
这是渲染的html:
<span id="ctl00_Body_CaseList918421504_ListControl_Pager_it" class="btn-group btn-group-sm">
<a class="disabled btn btn-default">|<</a>
<a class="disabled btn btn-default"><</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','')">></a>
<a class="btn btn-default" href="javascript:__doPostBack('ctl00$Body$CaseList918421504_ListControl$Pager$it$ctl02$ctl01','')">>|</a>
</span>
答案 2 :(得分:8)
除了理查德的答案之外......我使用他的方法并添加了对“禁用”和“活动”类以及周围div-Tag的支持 -
更新:我添加了John对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 == " ")
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 :(得分:1)
我对Andreas的回答做了其他更改。 Bootstrap示例将当前页面(活动)页面包装在超链接标记内,因此我注意到在选择大小变化(如pagination-lg或pagination-sm)时,某些Bootstrap模板无法正确格式化活动标记。这是我的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 == " ")
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();
}
}
}
}