在 asp.net 的 gridview 中保持整个分页排序

Maintain sorting throughout paging in gridview in asp.net

如何在 asp.net.

的 gridview 分页中保持排序

下面是我的绑定网格、分页和排序

的代码
private string SortDirection
{
    get { return ViewState["SortDirection"] != null ? ViewState["SortDirection"].ToString() : "ASC"; }
    set { ViewState["SortDirection"] = value; }
}
private void BindGV(string sortExpression = null)
{
    string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
    SqlConnection con = new SqlConnection(CS);
    SqlCommand cmd = new SqlCommand("SPGetEmpDetailes", con);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlDataAdapter sda = new SqlDataAdapter(cmd);
    using (DataTable dt = new DataTable())
    {
        sda.Fill(dt);
        if (sortExpression != null)
        {
            DataView dv = dt.AsDataView();
            this.SortDirection = this.SortDirection == "ASC" ? "DESC" : "ASC";

            dv.Sort = sortExpression + " " + this.SortDirection;
            EmployeeGV.DataSource = dv;
        }
        else
        {
            EmployeeGV.DataSource = dt;
        }
        EmployeeGV.DataBind();
    }

}

我是 .NET 的新手,我想在整个分页过程中保持排序,但我不知道该怎么做。

protected void EmployeeGV_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    EmployeeGV.PageIndex = e.NewPageIndex;
    BindGV();
}

protected void EmployeeGV_Sorting(object sender, GridViewSortEventArgs e)
{
    this.BindGV(e.SortExpression);

}

好的,既然我们这里有一个数据分页器,那么这意味着数据分页例程将 re-bind GV。所以,这意味着:

Loading up - first page load - we fill the grid
When we page - we fill the grid
When we sort - we fill the grid.

所以,从上面看,我们至少看到了 3 个地方。这表明我们需要(并且想要)一个例程来加载网格 - 因为我们有几个地方可以执行此操作。

而且我看到你对此有一个例程。我们稍微调整一下。

下一个:

我们 get/have 的排序值不会持久化,因此我们可以再次为此使用 ViewState。 (我再次看到你试图使用它)。

那么,让我们来展开一下。

首先,永远不要忘记这条规则:

您想在第一次加载页面时加载组合框、网格、列表框和任何数据,而且只是第一次加载页面,而且只是第一次。如果您违反此规则,那么您实际上无法构建一个有效的 Web 表单页面 - 您就是做不到!!!!

原因很简单:

任何按钮点击,任何 post-back,以及该页面上的任何代码操作将始终并且我重复总是将首先触发页面加载事件,然后是您的事件 -(按钮点击,分页或其他)。所以,这意味着我们总是会有我们的页面加载代码存根和一个 if (!IsPostBack) 代码存根 - (该死的总是遵循这种设计模式)。

好的,让我们编写代码。

下一步:我认为没有理由在某些使用块中放置数据表 - 它们可以自行安全处理。但是,为 sql 连接采用 using 块,以及 sql 命令对象之类的东西 - 是的,请应用 using 块。

好的,我认为我们已经解决了基本问题。

所以,让我们设置代码,像这样说:

所以,说出我们的简单标记 - 我们放置了一行 select 按钮。

    <div style="padding:35px;width:55%">
        <asp:GridView ID="GridView1" runat="server" 
            AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table"
            AllowPaging="True" OnPageIndexChanging="GridView1_PageIndexChanging" PageSize="8" AllowSorting="True" OnSorting="GridView1_Sorting">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="First" SortExpression="FirstName" />
                <asp:BoundField DataField="LastName" HeaderText="Last" SortExpression="LastName" />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
                <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
                <asp:CheckBoxField DataField="Active" HeaderText="Active" ItemStyle-HorizontalAlign="Center" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button runat="server" Text="View" CssClass="btn" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <PagerStyle CssClass="GridPager" />
        </asp:GridView>
    </div>

好的,现在我们的代码,这样说:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ViewState["MySort"] = "HotelName";
            BindGV();
        }
    }

    void BindGV()
    {
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (SqlCommand cmdSQL = new SqlCommand("SELECT * FROM MyHotels", conn))
            {
                conn.Open();
                DataTable rstData = new DataTable();
                rstData.Load(cmdSQL.ExecuteReader());
                // apply optional sort
                if (ViewState["MySort"] != null)
                    rstData.DefaultView.Sort = ViewState["MySort"] as string;

                GridView1.DataSource = rstData;
                GridView1.DataBind();
            }
        }
    }

    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.PageIndex = e.NewPageIndex;
        BindGV();
    }

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
        ViewState["MySort"] = e.SortExpression;
        BindGV();
    }

现在我们明白了:

那么,技巧还是方法?

我们有一个视图状态来保存我们的排序 - 当我们想要排序时,我们只需放入这个 ViewState["MySort"] = 一些列进行排序。之后,我们的 bind + load 例程可以自由 运行 - 如果设置了,我们就会排序。

因此,分页例程、排序例程和加载例程 -- 它们都调用一个例程,因此我们不必编写大量代码。

还有查看按钮?好吧,如果我们像这样单击那个按钮(假设我们添加一个单击事件):

然后行按钮点击可以是这样的:

    protected void Unnamed_Click(object sender, EventArgs e)
    {

        Button btn = sender as Button;
        GridViewRow gRow = btn.NamingContainer as GridViewRow;

        Debug.Print("Row index click = " + gRow.RowIndex.ToString());
        // get database (hidden pk row id
        int? PKID = GridView1.DataKeys[gRow.RowIndex]["ID"] as int?;

        Debug.Print("Database PK = " + PKID.ToString());
        Debug.Print("Hotel name this row = " + gRow.Cells[2].Text);
    }

然后点击,我们得到: