Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

GridView sorting issue with one column

Status
Not open for further replies.

AzizKamal

Programmer
Apr 6, 2010
122
PK
I am using GridView control in an aspx page. I need to implement sorting on columns such that when the user clicks on any column, if the sort order is ascending, it changes to descending and vice versa.

GridView aspx page has the following content:

Code:
<asp:gridview id="grdData"
        runat="server" BorderColor="#DEBA84" AutoGenerateColumns=false
        BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2" AllowSorting=true OnSorting=grdData_Sorting
        ShowFooter="True" HorizontalAlign=Center EmptyDataText="There are no data records to display.">
        <Columns>
            <asp:BoundField DataField="Employee Number" HeaderText="Employee Number" SortExpression="Employee Number" FooterText="Total" />
            <asp:BoundField DataField="Employee Name" HeaderText="Employee Name" SortExpression="Employee Name" />
            <asp:BoundField DataField="Employee" HeaderText="Employee" SortExpression="Employee" ItemStyle-HorizontalAlign=Right DataFormatString="{0:N0}"  />
            <asp:BoundField DataField="Employer" HeaderText="Employer" SortExpression="Employer" ItemStyle-HorizontalAlign=Right DataFormatString="{0:N0}" />
            <asp:BoundField DataField="Avg Monthly Bal" HeaderText="Avg Monthly Bal" SortExpression="Avg Monthly Bal" ItemStyle-HorizontalAlign=Right DataFormatString="{0:N0}" />
            <asp:BoundField DataField="Interest" HeaderText="Interest" SortExpression="Interest" ItemStyle-HorizontalAlign=Right DataFormatString="{0:N0}" />
            <asp:BoundField DataField="Unit Name" HeaderText="Unit Name" SortExpression="Unit Name" />
        </Columns>
        <RowStyle BackColor=White ForeColor=Black />
        <FooterStyle BackColor=White Font-Bold="True" ForeColor=Maroon />
        <HeaderStyle BackColor=White Font-Bold="True" ForeColor=Maroon />
      </asp:gridview>

In aspx.vb page, I have declared the following in Partial Public Class [Inherits Class] section:

Code:
Private Const ASCENDING As String = " ASC"
    Private Const DESCENDING As String = " DESC"

When the data is assigned to GridView:
Code:
Dim view As DataView = New DataView(tmpTable)
        view.Sort = "Unit Name,Employee Number"
        grdData.DataSource = view
        Session("sortTable") = view.Table
        grdData.DataBind()

Following code is written for grdData gridView sorting:
Code:
Protected Sub grdData_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs)
        Dim sortExpression As String = e.SortExpression

        If GridViewSortDirection = SortDirection.Ascending Then
            GridViewSortDirection = SortDirection.Descending
            SortGridView(sortExpression, DESCENDING)
        Else
            GridViewSortDirection = SortDirection.Ascending
            SortGridView(sortExpression, ASCENDING)
        End If

    End Sub

Public Property GridViewSortDirection() As SortDirection
        Get
            If ViewState("sortDirection") Is Nothing Then
                ViewState("sortDirection") = SortDirection.Ascending
            End If

            Return DirectCast(ViewState("sortDirection"), SortDirection)
        End Get
        Set(ByVal value As SortDirection)
            ViewState("sortDirection") = value
        End Set
    End Property

Private Sub SortGridView(ByVal sortExpression As String, ByVal direction As String)
        
Dim dt As DataTable = GetData.Tables(0)

        Dim dv As New DataView(dt)
        dv.Sort = sortExpression + direction

        grdData.DataSource = dv
        grdData.DataBind()
    End Sub

Private Function GetData() As DataSet

        Dim ds As DataSet = New DataSet
        ds.Tables.Add(Session("sortTable").Copy)
        Return ds

    End Function

The issue I am facing is that gridView has 7 columns; Employee Number, Employee Name, Employee, Employer, Avg Monthly Bal, Interest, Unit Name

Whenever I click on any column, it is sorted in descending order on first click, in ascending order on second click and so on. But this is not the case with Employee Number column. Employee Number column is not working as desired. On first click, it retains its order, then changes to descending, then ascending. For example, in a sample data, I had the following values in GridView rows for Employee Number columns:
890
2975
2592

When I clicked on Employee Number, it again showed:
890
2975
2592

Upon second click, it showed:
2592
2975
890

Upon third click, it showed:
890
2975
2592

It is the first click on Employee Number, that is the issue

 
you will need to store the column as well as the direction between postbacks. also load the default column/sort (probablly employee number, ascending) when the page loads. this why you don't need to check for null/nothing. when sorting the logic would flow like this
Code:
var previous = GetPreviousColumnAndSortDirection();
if (previous.Column == e.ColumnName)
{
   if(previous.Direction == SortDirection.Ascending)
   {
       sort descending
   }
   else
   {
       sort ascending
   }
}
else
{
   sort ascending
}
store the current column and sort direction for use later.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
Thanks.

I changed the code and amended code is listed below:

Page Load:
Code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
    Session("sortColumn") = "Unit Name,Employee Number"
            Session("sortDirection") = ASCENDING
        End If
End Sub

GridView Sorting:
Code:
Protected Sub grdData_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs)

        If Session("sortColumn") = e.SortExpression Then
            If Session("sortDirection") = ASCENDING Then
                Session("sortColumn") = e.SortExpression
                Session("sortDirection") = DESCENDING
                SortGridView(e.SortExpression, DESCENDING)
            Else
                Session("sortColumn") = e.SortExpression
                Session("sortDirection") = ASCENDING
                SortGridView(e.SortExpression, ASCENDING)
            End If
        Else
            Session("sortColumn") = e.SortExpression
            Session("sortDirection") = DESCENDING
            SortGridView(e.SortExpression, DESCENDING)
        End If


    End Sub

After this, when I tested the application with amended code, even then, Employee Number column did not sort to descending order upon first click, on second click it changed to descending order, on third click it changed to ascending order.

Then I changed one thing in tmpTable whose view is assigned to grdData gridview.

Code:
Dim tmpTable As DataTable = New DataTable("IntrEmps")

        tmpTable.Columns.Add("Employee Number", Type.GetType("System.String"))
        tmpTable.Columns.Add("Employee Name", Type.GetType("System.String"))
        tmpTable.Columns.Add("Employee", Type.GetType("System.Double"))
        tmpTable.Columns.Add("Employer", Type.GetType("System.Double"))
        tmpTable.Columns.Add("Avg Monthly Bal", Type.GetType("System.Double"))
        tmpTable.Columns.Add("Interest", Type.GetType("System.Double"))
        tmpTable.Columns.Add("Unit Name", Type.GetType("System.String"))

I changed this:
Code:
tmpTable.Columns.Add("Employee Number", Type.GetType("System.String"))

to this:
Code:
tmpTable.Columns.Add("Employee Number", Type.GetType("System.Double"))

Now on first click, Employee Number column sorted to descending order, on second click to ascending order…
 
After this, when I tested the application with amended code, even then, Employee Number column did not sort to descending order upon first click, on second click it changed to descending order, on third click it changed to ascending order.
this makes perfect sense. your default sort is [tt]Unit Name,Employee Number[/tt].
[tt]Unit Name,Employee Number != Employee Number[/tt] so the [tt]else ascending[/tt] block would execute. if you change the default sort to [tt]Employee Number[/tt] clicking [tt]Employee Number[/tt] once would sort descending, clicking a second time would sort ascending.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
Thanks.

My code has the else descending block instead of else ascending block.

Code:
If Session("sortColumn") = e.SortExpression Then
            If Session("sortDirection") = ASCENDING Then
                Session("sortColumn") = e.SortExpression
                Session("sortDirection") = DESCENDING
                SortGridView(e.SortExpression, DESCENDING)
            Else
                Session("sortColumn") = e.SortExpression
                Session("sortDirection") = ASCENDING
                SortGridView(e.SortExpression, ASCENDING)
            End If
        [blue]Else
            Session("sortColumn") = e.SortExpression
            Session("sortDirection") = DESCENDING
            SortGridView(e.SortExpression, DESCENDING)[/blue]
        End If

I did it like this because default sort is ascending. If else block were ascending, nothing would happen on first click.

As I understood it, this is due to the data type of Employee Number in tmpTable datatable. Earlier it was String and now it is Double.

To check it, I also tested it in Excel.
I selected cells A1,A2,A3,A4 and changed the Format from General to Text.

Then I typed:
Emp#
890
2975
2592

Then I selected cells A1:A4, Data -> Sort.
Checked My data has headers
Sort by (Column A)
Sort On (Values)
Order (A to Z)
Clicked OK

There were two options:
1. Sort anything that looks like a number, as a number
2. Sort numbers and numbers stored as text separately

I selected option 2 and clicked OK. Although the sort order selected was A to Z, still I got the following result:
Emp#
2592
2975
890

Then I repeated again but this time with option 1 and I got the following result:
Emp#
890
2592
2975
 
a number as a string vs. a number as a number will sort differently.

Jason Meckley
Programmer
Specialty Bakers, Inc.

faq855-7190
faq732-7259
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top