First thing you need to do is to provide each of your column, that is to be sorted, with a sorting expression. The sorting expression should be exaclty the same as the name of the field that is being binded to the column. I am assuming you have already done that. In my application i have a method called BindData( string SortExpr ). this method first creates a dataview object, initializing it to the table with data. This table is in a dataset. Then the argument SortExpr is assigned to the .sort property of the dataview. finally the dataview is assigned to the datagrid's source property. E.g. dv=new DataView(ds.Tables[0]); dv.Sort=SortingExpr; dg.DataSource=dv; dg.DataBind(); This how the grid is bind every time. The argument sortExpr is empty string for the first load. Now for the main function: For bidirectional sorting in aspx, u need to keep track of the direction to which the last sorting was performed. For this i have used ViewSate variables; one for each column. I have initialized them with 1 denoting that the last sort was in desc. order. Becareful in naming the ViewState variables. You must name them w.r.t the sorting expression of the columns for all this to work! E.g. for a column with "User" as the sorting expression initialize a viewstate as follows: ViewState["User"])==1; The follwing is the sample of my SortRecord() Method. protected void SortRecords(object sender, DataGridSortCommandEventArgs e) { string strTargetSortDirection=""; switch(e.SortExpression.ToString()) { case "User": { SetSortParameters(e.SortExpression); if((int)(ViewState["User"])==0) { strTargetSortDirection =" ASC"; } else { strTargetSortDirection=" DESC"; } break; } } CurrentSortingExpr = e.SortExpression + strTargetSortDirection; BindData(CurrentSortingExpr); } In the above method each case represents the sorting expression of a column. So the number of cases will be equal to the number of columns to be sorted. In every case first a method SetSortParameters(...) is called with the current sorting expression as the argument. This will change the viewstate value for the column and will be revered every time. The body of SetSortParameters(...) is given below: private void SetSortParameters(string trgColumnName) { if((int)(ViewState[trgColumnName])==1) { ViewState[trgColumnName]=0; } else { ViewState[trgColumnName]=1; } } I know its pretty lengthy but very simple once you get the lo