ASP.NET 4.5 GridView:最后一页的PostBack

Git*_*rai 8 .net c# asp.net paging gridview

我在ASP.NET 4.5和4.5.1版本中发现了GridView寻呼机的问题.从.NET 2 - 4开始,我从未遇到过这样的问题.

到目前为止,我有一个gridview,我在后面的代码中填充数据,如下所示:

protected int CurrentPage { get { return SearchResults.PageIndex + 1; } }

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
         BindGrid();
}

private void BindGrid()
{
    int totalRowCount = 0;
    SearchResults.DataSource = GetPageData(SearchResults.PageIndex, SearchResults.PageSize, out totalRowCount);
    SearchResults.VirtualItemCount = totalRowCount;                   
    SearchResults.DataBind();
}

private IEnumerable GetPageData(int start, int count, out int totalRowCount)
{
    return Membership.GetAllUsers(start, count, out totalRowCount);
}

protected void SearchResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{            
    SearchResults.PageIndex = e.NewPageIndex;            
    BindGrid();
}
Run Code Online (Sandbox Code Playgroud)

问题是如果我点击GridView的最后一页并尝试返回任何其他页面,我的PageIndexChanging不会触发.仅当最后一页与PageSize没有相同的记录计数时,才会出现此问题.行为是我的页面被重新加载,gridview的页面填充了空的数据行直到PageSize.VirtualItemCount正确表示总ItemCount.

标记,如果你在那里找到了什么:

<asp:GridView runat="server" CellPadding="0" CellSpacing="0" GridLines="None" CssClass="table table-condensed table-striped table-footer"
        ID="SearchResults" AllowCustomPaging="true" AllowPaging="true" PageSize="6" OnPageIndexChanging="SearchResults_PageIndexChanging" AutoGenerateColumns="false" UseAccessibleHeader="true">
...
<PagerTemplate>
            <span class="pull-left">
                <strong><%= SearchResults.PageIndex * SearchResults.PageSize + 1 %></strong> - <strong><%= CurrentPage * SearchResults.PageSize %></strong>
            </span>
            <span class="pull-left">
                Total records: <strong><%= SearchResults.VirtualItemCount %></strong>
            </span>
            <ul class="pagination pull-right">
                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="First"><span class="glyphicon glyphicon-backward"></span></asp:LinkButton></li>

                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage - 2 %>" Visible="<%# CurrentPage > 2 %>"><%= CurrentPage - 2 %> </asp:LinkButton></li>
                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage - 1 %>" Visible="<%# CurrentPage > 1 %>"><%= CurrentPage - 1 %> </asp:LinkButton></li>
                <li class="active"><a href="#"><%= CurrentPage %></a></li>
                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage + 1 %>" Visible="<%# CurrentPage < SearchResults.PageCount %>"><%= CurrentPage + 1 %></asp:LinkButton></li>
                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage + 2 %>" Visible="<%# CurrentPage < SearchResults.PageCount - 1 %>"><%= CurrentPage + 2 %></asp:LinkButton></li>

                <li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="Last"><span class="glyphicon glyphicon-forward"></span></asp:LinkButton></li>
            </ul>
        </PagerTemplate>
</asp:GridView>
Run Code Online (Sandbox Code Playgroud)

非常感谢,我已经处理了好几天了.当然我可以使用QueryString方法,但由于我将使用很多表,我想坚持使用回发方法,如果可能的话......


编辑:

我发现最简单的解决方法是在每个Page_Load上做一个BindGrid.由于某种原因,除非LastPageSize == PageSize,否则PageIndexChanging不会在最后一页上触发.然后不会调用DataBind以绑定CommandArguments,因此我无法正确回发.

另一方面,它不是很清楚,可能会导致问题...至少双重绑定=对页面转换数据的SQL调用双重...否则,我不知道如何在这里强制PageIndexChanging,看起来像一个新的.NET问题给我.

Git*_*rai 2

由于我对我提出的解决方案不满意(给未来的开发带来了太多问题),我决定采用“控制开发”方式来确保一切都正确创建。无论我使用哪种类型的 PagerTemplate,都会发生这种情况 - 我正在使用一个,回发不会从最后一页触发。希望我不是唯一一个:-)

对于那些遇到同样问题的人,我提供了可以正常工作的自定义控件(当然,没有实现 PagerSettings 和 PagerTemplates,但带来了基本功能)。

public class ExtendedGridView : System.Web.UI.WebControls.GridView
{
    protected override void InitializePager(System.Web.UI.WebControls.GridViewRow row, int columnSpan, System.Web.UI.WebControls.PagedDataSource pagedDataSource)
    {
        HtmlGenericControl ul = new HtmlGenericControl("ul");

        ul.Attributes.Add("class", "pagination pull-right");

        AddPager(ul, commandArgument: "First", text: "<span class='glyphicon glyphicon-fast-backward'></span>");

        for (int i = 0; i < PageCount; i++)
        {
            AddPager(ul, i);
        }

        AddPager(ul, commandArgument: "Last", text: "<span class='glyphicon glyphicon-fast-forward'></span>");

        row.CssClass = "table-footer";
        row.Cells.Add(new System.Web.UI.WebControls.TableCell());
        row.Cells[0].ColumnSpan = columnSpan;
        row.Cells[0].Controls.AddAt(0, ul);            
    }

    protected virtual void navigate_Click(object sender, EventArgs e)
    {
        string commandArgument = ((System.Web.UI.WebControls.LinkButton)sender).CommandArgument.ToString();
        int pageIndex = 0;

        if (!int.TryParse(commandArgument, out pageIndex)) {
            switch (commandArgument)
            {
                case "First": pageIndex = 0; break;
                case "Last": pageIndex = PageCount - 1; break;
                case "Prev": pageIndex = PageIndex - 1; break;
                case "Next": pageIndex = PageIndex + 1; break;
            }
        }

        OnPageIndexChanging(new System.Web.UI.WebControls.GridViewPageEventArgs(pageIndex));
    }

    private void AddPager(System.Web.UI.Control parentControl, int pageIndex = -1, string commandArgument = null, string text = null)
    {
        HtmlGenericControl li = new HtmlGenericControl("li");

        if (pageIndex == PageIndex)
            li.Attributes.Add("class", "active");

        System.Web.UI.WebControls.LinkButton button = new System.Web.UI.WebControls.LinkButton();
        button.CommandName = "Page";

        if (text == null)
            button.Text = (pageIndex + 1).ToString();
        else
            button.Text = text;

        if (string.IsNullOrWhiteSpace(commandArgument))
            button.CommandArgument = string.Format("{0}", pageIndex);
        else
            button.CommandArgument = commandArgument;

        button.Click += navigate_Click;

        li.Controls.Add(button);
        parentControl.Controls.Add(li);
    }
}
Run Code Online (Sandbox Code Playgroud)

只需确保您的标记是: -AllowPaging="true" -AllowCustomPaging="false" -PageSize="whatever" - 并且您仍然在后面的代码中提供 VirtualItemCount

使用 SelectMethod 的代码可能如下所示:

protected void Page_Load(object sender, EventArgs e)
{

}

public IEnumerable SearchResults_GetData(int startRowIndex, int maximumRows, out int totalRowCount, string sortByExpression)
{
    int pageIndex = (int)(startRowIndex / maximumRows);
    return Membership.GetAllUsers(pageIndex, maximumRows, out totalRowCount);
}

protected void SearchResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    SearchResults.PageIndex = e.NewPageIndex;
    SearchResults.DataBind();
}
Run Code Online (Sandbox Code Playgroud)

由于这是我使用优秀的 Bootstrap 框架为 .NET 创建服务器端控件的好几次,因此我在此处创建了一个 git https://github.com/Gitzerai/Bootstrap.NET,我在其中放置了以引导程序正确方式呈现的控件。