何时填充排序的 asp:GridView



我试图用多种方式问这个问题。这是一个很难回答的问题,因为你必须了解发生了什么。

何时填充网格视图?


侄女的答案是在Page_Load期间,如果不是回发

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
       DataSet ds = GetStuffToShow();
       GridView1.DataSource = ds;
       GridView1.DataBind();
    }
}

这样做的问题是,如果它是回发,则网格不会填充。网格未填充的原因是我们已经关闭了网格的视图状态。

所以不要看IsPostBack

我们需要始终填充网格,无论是否回发:

protected void Page_Load(object sender, EventArgs e)
{
    DataSet ds = GetStuffToShow();
    GridView1.DataSource = ds;
    GridView1.DataBind();
}

这样做的问题是,如果用户对列进行排序,则在 Page_InitPage_Load 之后调用 OnSorting 事件:

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    DataSet ds = GetStuffToShow(e.SortExpression, e.SortDirection);
    GridView1.DataSource = ds;
    GridView1.DataBind();
}    

我们运行了两个数据库查询,而只需要一个。

缓存适用于列排序

如果我愿意在列排序期间接受无效缓存,我可以将DataSet存储在会话变量中,只要我将其用于任何其他操作即可。

问题是在我需要它Page_Load)后调用OnSorting事件:

protected void Page_Load(object sender, EventArgs e)
{
    if (AGridViewOnSortingEventIsntBeingRaised)
    {
       DataSet ds = GetStuffToShow();
       StoreTheDatasetInTheSessionSomehowInCaseTheyCallSortInTheFuture(ds);
       GridView1.DataSource = ds;
       GridView1.DataBind();
    }
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    DataSet ds = GetDataSetOutOfSessionSomehowThatDamnWellBetterBeThere();
    SomehowSortAReadOnlyDisconnectedDataSet(ds, e.SortExpression, e.SortDirection);
    GridView1.DataSource = ds;
    GridView1.DataBind();
}    

对未知的恐惧

然后我仍然感到恐惧,因为我关闭了 GridView 的视图状态。 我不认为只读asp:GridView需要数十千字节的base64编码,当我可以从服务器(或从内存)重建它时。

但我相信我有义务将GridView恢复到上次呈现页面时的状态。我必须在Page_Load之前(即在Page_Init期间)这样做。我有这种恐惧,因为有人这么说。所以我把它变成

protected void Page_Init(object sender, EventArgs e)
{
    if (AGridViewOnSortingEventIsntBeingRaised)
    {
       DataSet ds = GetStuffToShow();
       StoreTheDatasetInTheSessionSomehowInCaseTheyCallSortInTheFuture(ds);
       GridView1.DataSource = ds;
       GridView1.DataBind();
    }
}

这样做的问题是,GetStuffToShow取决于用户在文本框中键入的内容,这些内容在Page_Init期间不存在

无论如何,我在漫无边际。这里太热了。希望这个问题能得到回答,不像我最近对 asp.net 的其他挫折

奖金阅读

  • 对使用数据集形成的网格视图进行排序

通过添加几个隐藏字段,一个用于排序表达式,另一个用于排序方向,可以使用这些值在页面加载时填充一次 GridView,然后在排序事件中更新排序(从一体式代码框架 GridView 示例修改的排序代码):

    protected void Page_Load(object sender, EventArgs e)
    {
        DataSet ds = GetStuffToShow();
        GridView1.DataSource = ds;
        GridView1.DataBind();
    }
    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
        // If the sorting column is the same as the previous one, 
        // then change the sort order.
        if (SortExpression.Value.Equals(e.SortExpression))
        {
            SortDirection.Value = SortDirection.Value.Equals("ASC") ? "DESC" : "ASC";
        }
        // If sorting column is another column, 
        // then specify the sort order to "Ascending".
        else
        {
            SortExpression.Value = e.SortExpression;
            SortDirection.Value = "ASC";
        }
        var sortedView = new DataView(<convert your DataSet to a DataTable>)
            { Sort = string.Format("{0} {1}", this.SortExpression.Value, this.SortDirection.Value) };
        GridView1.DataSource = sortedView;
        GridView1.DataBind();
    }

请注意,SortDirection 和 SortExpression 是隐藏字段。 这也非常适合缓存数据集。

另外,我不会担心你提出的Page_Init问题。 仅当您动态创建控件时,这才应适用。

一个简单的

解决方案是对Page.Pre_Render事件调用Gridview.DataBind(),这使得它在处理任何按钮/排序事件后调用。这是确保每个请求仅调用一次的好方法。

为了更清楚起见,通过属性访问数据集也是一件好事,该属性基本上将在其 Set 部分中调用您的 "Store-The-Dataset-In-The-Session-Somehow-In-Case-They-Call-Sort-In-The-Future" 方法,在 Get 部分中调用您的"Get-Data-Set-Out-Of-Session-That-Had-Better-Be-There"

您可以尝试在 Gridview 需要数据源事件上填充网格当您执行回发并获得您在事件中编码的正确功能时,都会调用它。此外,如果您想再次绑定它,您可以只使用数据数据绑定方法,这将再次调用 needdatasource 事件

最新更新