如何以编程方式在 ASP.NET 4.0 GridView 上启用分页和排序?

Posted

技术标签:

【中文标题】如何以编程方式在 ASP.NET 4.0 GridView 上启用分页和排序?【英文标题】:How to enable Paging and Sorting on ASP.NET 4.0 GridView programmatically? 【发布时间】:2011-05-04 09:06:39 【问题描述】:

我正在使用 ASP.NET 4.0 和 C#(Visual Web Developer 2010 Express)。

我已经成功地使用声明性 ASP.NET 代码实现了一个绑定到存储过程数据源的简单 GridView,如下所示:

<asp:GridView 
    ID="grdTrades" 
    runat="server" 
    DataKeyNames="tradeId" 
    EnablePersistedSelection="true"
    SelectedRowStyle-BackColor="Yellow" 
    AllowPaging="true" 
    AllowSorting="true"
    PageSize = "20" 
    AutoGenerateColumns="false" 
    DataSourceID="sdsTrades" 
    >
    <Columns>
        <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
        <asp:BoundField DataField="tradeId" HeaderText="TradeId"  ReadOnly="True" SortExpression="tradeId" />
        < ... more columns ... >
    </Columns>
</asp:GridView>

<asp:SqlDataSource ID="sdsTrades" runat="server" 
    ConnectionString="<%$ ConnectionStrings:TradesDB %>" 
    ProviderName="<%$ ConnectionStrings:Trades.ProviderName %>"  
    SelectCommand="usp_GetTrades" SelectCommandType="StoredProcedure">      
</asp:SqlDataSource>

它很好用,包括分页和排序。我想删除 SqlDataSource 并使用代码隐藏(我试图将数据库访问代码放在一个地方)。到目前为止,我的代码隐藏中有这个:

protected void Page_Load(object sender, EventArgs e)

    if (!this.IsPostBack)
    
        grdTrades.SelectedIndex = 0;
        DBUtil DB = new DBUtil();
        grdTrades.DataSource = DB.GetTrades();
        grdTrades.DataKeyNames = new string[]  "tradeId" ;
        grdTrades.DataBind();            
    


// this is needed otherwise I get "The GridView 'grdTrades' fired event PageIndexChanging which wasn't handled."
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)

    grdTrades.PageIndex = e.NewPageIndex;
    grdTrades.DataBind();
    

我的声明性代码现在看起来像:

<asp:GridView 
    ID="grdTrades" 
    runat="server" 
    EnablePersistedSelection="true"            
    SelectedRowStyle-BackColor="Yellow" 
    AllowPaging="true" 
    AllowSorting="true"
    PageSize = "20" 
    AutoGenerateColumns="false" 

    OnPageIndexChanging="grdTrades_PageIndexChanging"
    >
    <Columns>
        <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
        <asp:BoundField DataField="tradeId" HeaderText="TradeId"  ReadOnly="True" SortExpression="tradeId" />
        < ... more columns ... >           
    </Columns>
</asp:GridView>

问题是当我单击页码时,页面变为空白。我也想实现排序,但想让分页首先工作。请帮忙。

谢谢

【问题讨论】:

【参考方案1】:

每次更改页面时都需要绑定 GridView。

例如:

void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e) 

    grdTrades.DataSource = DB.GetTrades();  
    grdTrades.PageIndex = e.NewPageIndex; 
    grdTrades.DataBind(); 
 

我的建议是将来自 DB.GetTrades() 的结果存储在 ViewState(或缓存)中,这样每次更改页面时都无需访问数据库。

不过,在执行此操作时,排序可能会变得相当困难。

您始终可以使用 ObjectDataSource 而不是 SqlDatasource。然后,您可以将 ObjectDataSource 指向您的 DB.GetTrades() 函数。排序和分页将自动工作。

希望对您有所帮助。

【讨论】:

如果你返回一个数据集,实际上排序只会在 ObjectDataSource 上自动工作,我相信(我可能是错的)。如果要返回 List,则需要创建自己的类,该类继承自 IComparere 类。 非常感谢 Jamie,工作正常。我想研究 ObjectDataSource 方法 - 如果您有时间,您能否提供一个快速示例来说明如何做到这一点?这听起来是一种表现更好、更明智的做法。 我不确定您是否正在使用业务对象,但这可能会帮助您入门:msdn.microsoft.com/en-us/library/9a4kyhcx.aspx。 ObjectDataSource 看起来像要走的路。非常好,感谢您的帮助。【参考方案2】:

您可以创建一个方法来绑定网格视图,而不是在分页中再次绑定它。通过创建绑定网格视图的方法,您可以随时调用该方法来绑定网格视图。

protected void Page_Load(object sender, EventArgs e)

   if (!this.IsPostBack)
   
       BindgrdTrades();            
   
private void BindgrdTrades()
   
      DBUtil DB = new DBUtil();
       grdTrades.DataSource = DB.GetTrades();
       grdTrades.DataKeyNames = new string[]  "tradeId" ;
       grdTrades.DataBind(); 
   


void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e) 
   

       grdTrades.PageIndex = e.NewPageIndex; 
       BindgrdTrades(); 
    

【讨论】:

【参考方案3】:

我不得不公开我的 _PageIndexChanging 计数器(我是 asp.net 的新手,我不知道它为什么重要)。该页面将通过一个错误说它找不到类。这些帖子对使用其他接近逐字逻辑的分页很有帮助。感谢所有的海报花时间把它布置得如此清晰。这是我最终得到的代码:

public partial class Requests : System.Web.UI.Page

    protected void Page_Load(object sender, EventArgs e)
    

        if (!this.IsPostBack)
        
            BindgrdBuilds();

        
    

    private void BindgrdBuilds()
    
        // Link GridView to datasource
        GridView1.DataSource = BuildData.getBuilddata();

        // Bind SQLDataSource to GridView after retrieving the records.
        GridView1.DataBind();

    

    public void GridView1_PageIndexChanging(Object sender, GridViewPageEventArgs e)
    
        // increment PageIndex
        GridView1.PageIndex = e.NewPageIndex;

        // bind table again
        BindgrdBuilds();

     

我坚持使用 AutoGenerated 列,并且我正在对我在上面未包含的 cs 页面上的数据进行一些行绑定,但这是我的 GridView 的 asp 代码:

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="GridView1" 
    OnRowDataBound="GridView1_RowDataBound" 
    OnPageIndexChanging="GridView1_PageIndexChanging"
    runat="server" 
    SelectedRowStyle-BackColor="Yellow" 
    AllowPaging="true" 
    AllowSorting="true"
    PageSize = "20" 
    AutoGenerateColumns="true" 
    <-- table formatting code trimmed -->
</asp:GridView>

我希望其他人可以利用此信息,此线程是一个很好的简单示例。现在分页可以正常工作了,是时候真正花哨并为 GridView1 取一个新名称了:D

【讨论】:

以上是关于如何以编程方式在 ASP.NET 4.0 GridView 上启用分页和排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行 asp.net 页面时以编程方式设置表格背景?

如何以编程方式登录到 ASP.NET Identity 2?

如何以编程方式检测我的应用程序是不是在 ASP.NET 页面内以 IIS 7.0 集成模式运行

当 Session.Abandon() 不起作用时,如何以编程方式结束 asp.net 中的会话?

asp.net C# 如何以编程方式更改 Page_Load 上的正文背景图像

在 Asp.Net 中以编程方式添加样式表