I am working of datagrid sorting. But GridViewStudents.dataSource is returning null in sorting function. I tried using session & viewstate. But doesn't work.
Any help appreciated.
My asp code for datagrid:
<asp:GridView ID="GridViewStudents" runat="server" AllowSorting="True"
onsorting="GridViewStudents_Sorting" ></asp:GridView>
Sorting function:
protected void GridViewStudents_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GridViewStudents.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
GridViewStudents.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridViewStudents.DataSource = dataView;
GridViewStudents.DataBind();
}
}
Sorting helper function:
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;
case SortDirection.Descending:
newSortDirection = "DESC";
break;
}
return newSortDirection;
}
Apply automatic sorting mode
dataGridView1.Columns["ColName"].SortMode = DataGridViewColumnSortMode.Automatic;
Try this....
DataGridView control is sorted using a column with a SortMode property value of Automatic, a sorting glyph is automatically displayed in the column header.
Make sure that you rebind your Gridview on each roundtrip. The datasource of a gridview is not automatically stored in gridview or viewstate. If you need to access the datasource, you need to propagate the datasource first.
I found the solution.
Hope it is useful for others.
For anyone who come across DataGridView sorting problem.
Remember 4 steps.
Declare global dataset object
static DataSet ds = null;
Load data to grid
if (!IsPostBack)
{
loadData();
}
Write sorting function
protected void GridViewStudents_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = new DataTable();
dataTable = ds.Tables[0];
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridViewStudents.DataSource = dataView;
GridViewStudents.DataBind();
}
}
Sorting helper function
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;
case SortDirection.Descending:
newSortDirection = "DESC";
break;
}
return newSortDirection;
}
Related
I work in C-sharp on ASP NET 4.
I need to add a sorting function to a column in a GridView. I've set the AllowSorting-property on the GridView to true and added sort expressions to the column.
Unfortunately, the sorting isn't working in the GridView.
Below is my code-behind-file for the column that should be able to sort, but I get the error
CS1502: The best overloaded method match for 'System.Data.DataView.DataView(System.Data.DataTable)' has some invalid arguments
on this line:
DataView sortedView = new DataView(BindData());
Code behind:
string sortingDirection;
public SortDirection dir
{
get
{
if (ViewState["dirState"] == null)
{
ViewState["dirState"] = SortDirection.Ascending;
}
return (SortDirection)ViewState["dirState"];
}
set
{
ViewState["dirState"] = value;
}
}
public string SortField
{
get
{
return (string)ViewState["SortField"] ?? "Name";
}
set
{
ViewState["SortField"] = value;
}
}
protected void gvProducts_Sorting(object sender, GridViewSortEventArgs e)
{
sortingDirection = string.Empty;
if (dir == SortDirection.Ascending)
{
dir = SortDirection.Descending;
sortingDirection = "Desc";
}
else
{
dir = SortDirection.Ascending;
sortingDirection = "Asc";
}
DataView sortedView = new DataView(RetrieveProducts());
sortedView.Sort = e.SortExpression + " " + sortingDirection;
SortField = e.SortExpression;
gvProducts.DataSource = sortedView;
gvProducts.DataBind();
}
protected void gvProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
if (dir == SortDirection.Ascending)
{
sortingDirection = "Asc";
}
else
{
sortingDirection = "Desc";
}
DataView sortedView = new DataView(RetrieveProducts());
sortedView.Sort = SortField + " " + sortingDirection;
gvProducts.DataSource = sortedView;
gvProducts.PageIndex = e.NewPageIndex;
gvProducts.DataBind();
}
private void BindData()
{
gvProducts.DataSource = RetrieveProducts();
gvProducts.DataBind();
}
private DataSet RetrieveProducts()
{
DataSet dsProducts = new DataSet();
string sql = " ... ";
using (OdbcConnection cn =
new OdbcConnection(ConfigurationManager.ConnectionStrings["ConnMySQL"].ConnectionString))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand(sql, cn))
{
........
}
}
return dsProducts;
}
Edit #1
DataView sortedView = new DataView(dsProducts.Tables[0]);
Edit # 2
I have added in aspx page:
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
But If clicked in Column Name I have this new error:
System.IndexOutOfRangeException: Cannot find table 0.
on this line:
Line 100: DataView sortedView = new DataView(dsProducts.Tables[0]);
The DataView class has only three constructors, in which one is default constructor DataView(), second one takes a DataTable as an argument DataView(DataTable), the other one takes four arguments DataView(DataTable, String, String, DataViewRowState).
The DataView constructor expects arguments of any one of these types, but your code has argument of some other type. That's the error.
Your BindData method should return a DataTable object,
//This function should return a Datatable
private void BindData()
{
gvProducts.DataSource = RetrieveProducts();
gvProducts.DataBind();
}
which you can pass into your DataView here.
DataView sortedView = new DataView(BindData());
For your second edit,
System.IndexOutOfRangeException: Cannot find table 0.
on this line:
Line 100: DataView sortedView = new DataView(dsProducts.Tables[0]);
I guess the dataset is empty, the error clearly states that there isn't any table in the dataset at position 0. So check whether your dataset has tables or not. Might be your sql request didn't get any table to fill in the dataset.
Else you might have created a new instance of the dataset.
I can't seem to get this right, even after looking at a few examples.
I've got this code, which happily re-sorts my gridview in an Ascending order:
// gridViewSorting and ConvertSortDirectionToSql are both necessary to ensure the gridview can sort when their column headers are
// clicked. You must remember to add (AllowSorting="True" OnSorting="gridViewSorting") to the gridview tag on the ASP side
protected void gridViewSorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GVInactive.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
string SQL = "[" + e.SortExpression + "] " + ConvertSortDirectionToSql(e.SortDirection);
dataView.Sort = SQL;
GVInactive.DataSource = dataView.ToTable();
GVInactive.DataBind();
}
}
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "DESC";
break;
case SortDirection.Descending:
newSortDirection = "ASC";
break;
}
return newSortDirection;
}
However, the second time I click on the header it's supposed to reverse the previous sorting order. It never does. Every time I click the header of a column, it hits the case SortDirection.Ascending: line and sets newSortDirection = "DESC". The data is sorted in descending order, yet when I click the header again it resolves SortDirection to Ascending.
Any ideas?
We use a ViewState variable to store the latest Sort Direction. When the grid is sorted we compare the Sort Criteria and Sort Direction of the grid with the ViewState variables which stores last sort expression. If the columns are equal then check the direction of the previous sort and sort in the opposite direction.
Example:
private string SortCriteria
{
get
{
if (ViewState["sortCriteria"] == null)
{
ViewState["sortCriteria"] = "";
}
return ViewState["sortCriteria"].ToString();
}
set
{
ViewState["sortCriteria"] = value;
}
}
private string SortDirection
{
get
{
if (ViewState["sortDirection"] == null)
{
ViewState["sortDirection"] = "";
}
return ViewState["sortDirection"].ToString();
}
set
{
ViewState["sortDirection"] = value;
}
}
protected void gvData_Sorting(object sender, GridViewSortEventArgs e)
{
gvData.EditIndex = -1;
if (SortCriteria == e.SortExpression)
{
if (SortDirection == string.Empty || SortDirection == "DESC") { SortDirection = "ASC"; }
else { SortDirection = "DESC"; }
}
else
{
SortCriteria = e.SortExpression;
SortDirection = "ASC";
}
BindGrid();
}
private void BindGrid()
{
DataTable dt = new [However you get dataset from database];
DataView dv = new DataView(dt);
dv.Sort = string.Format("{0} {1}", SortCriteria, SortDirection).Trim();
gvData.DataSource = dv;
gvData.DataBind();
}
For the record, I replaced the code used in my question with this, and it worked perfectly:
// gridViewSorting and ConvertSortDirectionToSql are both necessary to ensure the gridview can sort when their column headers are
// clicked. You must remember to add (AllowSorting="True" OnSorting="gridViewSorting") to the gridview tag on the ASP side
protected void gridViewSorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GVInactive.DataSource as DataTable;
string sortExpression = e.SortExpression;
string direction = string.Empty;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
if (SortDirection == SortDirection.Ascending)
{
SortDirection = SortDirection.Descending;
direction = " DESC";
}
else
{
SortDirection = SortDirection.Ascending;
direction = " ASC";
}
DataTable table = GVInactive.DataSource as DataTable;
table.DefaultView.Sort = sortExpression + direction;
GVInactive.DataSource = table;
GVInactive.DataBind();
}
}
public SortDirection SortDirection
{
get
{
if (ViewState["SortDirection"] == null)
{
ViewState["SortDirection"] = SortDirection.Ascending;
}
return (SortDirection)ViewState["SortDirection"];
}
set
{
ViewState["SortDirection"] = value;
}
}
I can probably remove a few lines (not sure I even need the DataView anymore), but it works perfectly as is. Just remember to add these pieces to the ASP side in the GridView tag:
AllowSorting="True" OnSorting="gridViewSorting"
and then change your gridview's name where appropriate.
See the below code, I am try to sorting Grid view data by calling function provided by the Microsoft vs 2008, but the paging is done well but the sorting process is not work, tell me where should i change the following code and yes i put grid view in updated penal,is there problem regarding to update penal?
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
showData();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
try
{
SqlCommand cmd = new SqlCommand("showData", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0] != null)
{
ds.Tables[0].DefaultView.Sort = e.SortExpression + " " + sortType(e.SortDirection);
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
}
}
private string sortType(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "DESC";
break;
case SortDirection.Descending:
newSortDirection = "ASC";
break;
}
return newSortDirection;
}
Can you ensure AllowSorting="true" and OnSorting="GridView1_Sorting"
Also refer
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorting.aspx
http://www.codeproject.com/Articles/26882/Gridview-Sorting-with-Up-and-Down-Icons-Paging
sorting and paging with gridview asp.net
http://www.c-sharpcorner.com/uploadfile/afenster/gridview-sorting/
Hope this helps
i think you have to assign dataview to the DataSource property of gridview, not the dataset object. like this
DataTable dt = ds.Tables[0];
DataView dv = new DataView(dt);
dv.Sort = e.SortExpression + " " + sortType(e.SortDirection);
GridView1.DataSource = dv;
GridView1.DataBind();
you are missing a default value for newSortDirection.
private string sortType(SortDirection sortDirection)
{
string newSortDirection = "ASC";
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "DESC";
break;
case SortDirection.Descending:
newSortDirection = "ASC";
break;
}
return newSortDirection;
}
I have a gridview and its data source comes from linq to sql statements:
var query = from user in dataContext.tbl_files
select new { user.File_Name, user.Upload_Time, user.Uploaded_By };
GridView1.DataSource = query.ToList();
GridView1.DataBind();
I am trying to implement sorting feature of gridview :
public void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
string previousSortExpression = (string)ViewState["SortDirection"];
string sortExpression = e.SortExpression;
SortDirection sortDirection = e.SortDirection;
if (sortExpression.Equals(previousSortExpression))
{
sortDirection = SortDirection.Descending;
ViewState["SortDirection"] = string.Empty;
}
else
ViewState["SortDirection"] = sortExpression;
string direction = sortDirection == SortDirection.Ascending ? "ASC" : "DESC";
e.SortExpression = string.Format("it.{0} {1}", e.SortExpression, direction);
DataTable dataTable = (DataTable)GridView1.DataSource; // here returns null!
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression ;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
But " DataTable dataTable = (DataTable)GridView1.DataSource; " line returns null however count of datasource is 4. I got this error :
{"Unable to cast object of type 'System.Collections.Generic.List1[<>f__AnonymousType03[System.String,System.Nullable`1[System.DateTime],System.String]]' to type 'System.Data.DataTable'."}
How can I sort my gridview and correct my mistake? Thanks..
You can't use the DataSource property of the grid to fetch the data source. It is only available after it is set and to the end of that postback. You'll need the fetch the data from the database again.
Something like this:
public void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
var users = (from user in dataContext.tbl_files
select new { user.File_Name, user.Upload_Time, user.Uploaded_By }).ToList().AsEnumerable();
switch(e.SortExpression)
{
case "File_Name":
users = users.OrderBy(x => x.File_Name);
break;
case "Upload_Time":
users = users.OrderBy(x => x.Upload_Time);
break;
case "Uploaded_By":
users = users.OrderBy(x => x.Uploaded_By);
break;
}
if(e.SortDirection == SortDirection.Descending)
users = users.Reverse();
GridView1.DataSource = users;
GridView1.DataBind();
}
Above answer is correct first you need to assign datasource to gridview again as sorting event is called.
So have to store the data somewhere.
For retrieving the datasource from grid you can follow below steps
The problem lies as you are assigning linq result as datasource of gridview and then taking datatable from the gridview datasource.
Try this code
BindingSource bs = (BindingSource )Gv.DataSource;
DataTable Dt = (DataTable ) bs.DataSource;
Contact if you have any doubt
I am trying Sorting functionality in Grid view but its not working.Can some body help?
Code:
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;
case SortDirection.Descending:
newSortDirection = "DESC";
break;
}
return newSortDirection;
}
protected DataSet FillDataSet()
{
string source = "Database=GridTest;Server=Localhost;Trusted_Connection=yes";
con = new SqlConnection(source);
cmd = new SqlCommand("proc_mygrid", con);
ds = new DataSet();
da = new SqlDataAdapter(cmd);
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
return ds;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GridView1.DataSource as DataTable;
if (dt != null)
{
DataView dv = new DataView(dt);
dv.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dv;
GridView1.DataBind();
}
Here dt is coming null.why? pls help thanks.
EDIT:
enter code here <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333"
GridLines="None" AllowPaging="true" AllowSorting="true" PageSize="12"
onpageindexchanging="GridView1_PageIndexChanging"
onsorting="GridView1_Sorting">
EDIT(Total code)
public partial class _Default : System.Web.UI.Page
{
SqlConnection con;
SqlCommand cmd;
DataSet ds;
SqlDataAdapter da;
protected void Page_Load(object sender, EventArgs e)
{
}
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;
case SortDirection.Descending:
newSortDirection = "DESC";
break;
}
return newSortDirection;
}
protected DataSet FillDataSet()
{
string source = "Database=GridTest;Server=Localhost;Trusted_Connection=yes";
con = new SqlConnection(source);
cmd = new SqlCommand("proc_mygrid", con);
ds = new DataSet();
da = new SqlDataAdapter(cmd);
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
return ds;
}
protected void GetValues(object sender, EventArgs e)
{
FillDataSet();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
int newPagenumber = e.NewPageIndex;
GridView1.PageIndex = newPagenumber;
GridView1.DataSource = FillDataSet();
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataSet ds = FillDataSet();
DataTable dt = ds.Tables[0];
if (dt != null)
{
dt.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dt;
GridView1.DataBind();
}
CODE:
private string GetSortDirection(string column)
{
string sortDirection = "DESC";
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "DESC"))
{
sortDirection = "ASC";
}
}
}
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = ((DataSet)Session["myDataSet"]).Tables[0];
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Because you're setting a DataSet as DataSource and then casting it to DataTable with the operator as.
The 'as' operator in C# is a tentative cast - if it's impossible to cast (types are not compatible) instead of throwing an exception as the direct cast the 'as' operator sets the reference to null.
If you only have one datatable in your dataset then you can get the first element like this:
ds.Tables[0];
... or use the name of the table:
ds.Tables["myTable"];
in your case you can try...
DataTable dt = GridView1.DataSource.Tables[0] as DataTable;
Hope it helps!
EDIT:
with regards to your sorting problem (once you get the datatable):
if (dt != null)
{
dt.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataBind();
}
You can do this because dt is a reference to the exact same object that's already set as DataSource for your grid. It should do the trick - if not there's smt else I am missing (such as we're sorting the wrong table meaning you have more than one table in the DataSet).
EDIT:
had a look at your code. I don't know exactly when GetValues gets fired but I suspect it's causing your problem (I think it might be overriding your sorting or smt along those lines).
If you comment out FillDataSource from getValues and modify your PageLoad to do this:
void Page_Load(Object sender, EventArgs e)
{
// Load data only once, when the page is first loaded.
if (!IsPostBack)
{
Session["myDataSet"] = FillDataSet();
}
}
then in your sort method you retrieve the DataSource like this:
DataTable dt = ((DataSet)Session["myDataSet"]).Tables[0];
Also you can retrieve the DataSet from session in your pagination handler method.
You should also notice an improvement in performance since you're retrieving the stuff form the db just once.
Give it a shot!
In Testing.aspx.cs
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
if (dataset != null)
{
datatable = dataset.Tables[0];
DataView dataView = new DataView(datatable);
dataView.Sort = e.SortExpression;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
In Testing.aspx
<asp:GridView ID="GridView1" runat="server"
AllowSorting="True" OnSorting="GridView1_Sorting">