5

我尝试过多种方式来问这个问题。这是一个很难回答的问题,因为您必须了解正在发生的事情。

什么时候填充 GridView?


nieve的答案是在 PostBack 期间Page_Load,如果不是PostBack的话:

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();
}

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

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

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

缓存适用于列排序

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

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

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的其他 挫败感

奖金阅读

4

3 回答 3

0

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

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

于 2013-07-26T14:08:26.530 回答
0

您可以尝试在 Gridview Needdatasource 事件上填充网格,当您执行回发并获得适当的功能时,该事件将被调用,无论您在事件中编写什么代码。另外,如果您想再次绑定它,您可以只使用 data databind 方法,这将再次调用 needdatasource 事件

于 2013-12-04T06:24:11.623 回答
0

通过添加几个隐藏字段,一个用于排序表达式,另一个用于排序方向,您可以使用这些值在页面加载时填充 GridView,然后在 Sorting 事件中更新排序(排序代码从 All -In-One 代码框架 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 是隐藏字段。这也很适合缓存 DataSet。

另外,我不会担心您提出的 Page_Init 问题。这仅适用于动态创建控件的情况。

于 2012-07-04T01:17:14.243 回答