Carlos Mendieta
Carlos Mendieta

Reputation: 872

ASP.NET Gridview Paging and Sorting events not working properly

I have a gridview that I load some ticket data into. Depending on the user action, this gridview will load up different sqldatasources and redisplay the data.

Here is the markup for the gridview:

<X:GridViewX ID="gvxTaskList" runat="server"
    AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False"
    Width="100%" Height="100%" CssClass="tablestyle"
    OnRowCreated="gvxTaskList_RowCreated"
    OnPageIndexChanging="gvxTaskList_PageIndexChanging"
    OnSorting="gvxTaskList_Sorting">

So, I have two problems.

First, the sorting event does not work at all for me. I get a null in the datatable. The code:

protected void gvxTaskList_Sorting(object sender, GridViewSortEventArgs e)
{
    try
        {
            System.Data.DataTable dataTable = gvxTaskList.DataSource as  
                                                  System.Data.DataTable;

            if (dataTable != null)
            {
                System.Data.DataView dataView = new System.Data.DataView(dataTable);
                dataView.Sort = e.SortExpression + " " +   
                                    ConvertSortDirectionToSql(e.SortDirection);

                gvxTaskList.DataSource = dataView;
                gvxTaskList.DataBind();
            }
        }
        catch (Exception ex)
        {
        }
    }

    private string ConvertSortDirectionToSql(SortDirection sortDirection)
    {
        string newSortDirection = String.Empty;
        try
        {
            switch (sortDirection)
            {
                case SortDirection.Ascending:
                    newSortDirection = "ASC";
                    break;

                case SortDirection.Descending:
                    newSortDirection = "DESC";
                    break;
            }                
        }
        catch (Exception ex)
        {
        }
        return newSortDirection;
    }     

Fails at if (dataTable != null) because, well, it IS null.

Second problem is the paging. When it first loads the gridview, paging is fine. I have two pages worth of data onload. i can page back and forth all day with no errors. The problem is when I change datasources and bring back three pages of data. I try to click on page 3 immediately from the first page and it reloads the previous data (with two pages). Any help would be appreciated.

Upvotes: 1

Views: 4210

Answers (1)

Gregory A Beamer
Gregory A Beamer

Reputation: 17010

I started to answer directly, but I wouold rather this be an exercise in thought. Run through your code for a second and look at what you are doing.

  1. Pull the data from the grid
  2. Sort the data
  3. Bind the data back to the grid

Not a good pattern, right? Why? Because if you get anything but NULL, you have already bound the form, which will cause the databind to blow up. And, if you get NULL, you cannot sort, which is what you are experiencing.

A better pattern is to separate the data concept from the container that displays it (effectively, separate the domain model (in this case as a datatable) from the UI elements). This means you bind one way each time.

How? Get the data. If you are merely adjusting (same data, different sort, for example), you can store a copy on the server between posts (in session is one example, but there are other means). You can then sort the data and bind. If it is paging, you request the next set and bind.

The idea is you are not relying on some harry potter magic that appears to be state, as the web is stateless. Instead, you assume statelessness and control the flow every time.

Now, Allov had an interesting idea to spur some more thought. I don't find it completely relevant to the question, but I do find it very useful to understand flow in a web page. If you load in Page_Load everytime, you have data, but realistically it is a bad pattern to use Page_Load for anything other than a non-postback event ... unless something is done either a) every time the page loads [more likely] or b) every time there is a postback [very unlikely, as you will have event handlers].

What this means is a Get Page.PostBack == false is when you load from Page_Load and you handle everything else with events.

You have this with your Sort event, but you are expecting to pull data from the GridView, which means you expect it to already be bound. But, if it is already bound, you have to clear it out to bind, which can even get impossible in some cases. In this case, you are lucky, as you are getting a null, which means you are not binding on top of binding (ouch!!!). The sort method args are useful for determining user expectations, but you should take control of the data yourself and bind it. this can be a trip to the database every time, or you can have it "cached" and bind from the cache. if you do a lot of items like sorting, "caching" works best. Session is one place you can "cache" between page hits.

Hope this makes sense.

Upvotes: 2

Related Questions