How to implement sorting functionality in gridview? - c#

I am trying to implement sorting functionality in grid view but its not working..
Code:
//enter code here
public partial class _Default : System.Web.UI.Page
{
SqlConnection con;
SqlCommand cmd;
DataSet ds;
SqlDataAdapter da;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["myDataSet"] = FillDataSet();
}
}
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)
{
//DataSet ds = FillDataSet();
DataTable dt = ((DataSet)Session["myDataSet"]).Tables[0];
if (dt != null)
{
dt.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Can somebody suggest where I am going wrong?
EDIT:
enter code here DataTable dtbl = ((DataSet)Session["myDataSet"]).Tables[0];
dtbl.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dtbl;
GridView1.DataBind();

Here is the running 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 dtbl = ((DataSet)Session["myDataSet"]).Tables[0];
dtbl.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dtbl;
GridView1.DataBind();
}

Related

How to pass a list of objects to a gridview datasource without generating a column error

I do a basic SQL query to feed data to a Gridview sort event.
public DataTable GetDataDataTableGeneric()
{
string query = "SELECT * FROM Gamer";
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["AzureServer"].ConnectionString);
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
conn.Close();
return dt;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
// string query= e.SortExpression + " " + GetSortDirection(e.SortExpression);
// e.SortExpression;
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
List<DataRow> list = dt.AsEnumerable().ToList();
GridView1.DataSourceID = null;
GridView1.DataSource = list;
GridView1.DataBind();
}
Since the datasource won't accept a non-enumerable object, I decided to convert the datatable to list.
However, I get this error:
'System.Data.DataRow' does not contain a property with the name 'Id'.
Is there a way to generate a list and avoid the error?
UPDATE
Function:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
// List<Gamer> list = dt.AsEnumerable().ToList();
List<Gamer> list = (from DataRow row in dt.Rows
select new Gamer
{
//assign properties here
Id = Convert.ToInt32(row["Id"]),
UserID = Convert.ToInt32(row["UserID"]),
Level = Convert.ToInt32(row["Level"]),
Loyalty = Convert.ToInt32(row["Loyalty"]),
Experience = Convert.ToInt32(row["Experience"]),
OverallPoints = Convert.ToInt32(row["OverallPoints"]),
OverallBets = Convert.ToInt32(row["OverallBets"]),
Login = row["Login"].ToString()
}).ToList();
GridView1.DataSourceID = null;
GridView1.DataSource = list;
GridView1.DataBind();
}
Error
The data source does not support sorting.
The following solution failed too. Resulting in the same sorting problem.
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
List<Gamer> list = (from DataRow row in dt.Rows
select new Gamer
{
//assign properties here
Id = Convert.ToInt32(row["Id"]),
UserID = Convert.ToInt32(row["UserID"]),
Level = Convert.ToInt32(row["Level"]),
Loyalty = Convert.ToInt32(row["Loyalty"]),
Experience = Convert.ToInt32(row["Experience"]),
OverallPoints = Convert.ToInt32(row["OverallPoints"]),
OverallBets = Convert.ToInt32(row["OverallBets"]),
Login = row["Login"].ToString()
}).ToList();
DataTable dt2 = ConvertToDataTable(list);
GridView1.DataSourceID = null;
GridView1.DataSource = dt2;
GridView1.DataBind();
}
private DataTable ConvertToDataTable<T>(IList<T> data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
{
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
return table;
}
The following solution has failed to work too:
string cmd = "SELECT * FROM Gamer ORDER BY "+ e.SortExpression + " " + GetSortDirection(e.SortExpression);
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter sqlAdapter = new SqlDataAdapter(cmd, connection);
sqlAdapter.Fill(ds);
}
GridView1.DataSource = ds;
GridView1.DataBind();
This does not makes sense, what is actually getting achieved by converting it to List<DataRow> and you are not converting it to List<Gamer>, so this way it woldn't work.
What you can do is directly bind it with datatable:
GridView1.DataSource = dt;
GridView1.DataBind();
or the other way around is to create a class which will be a DTO against your table :
public class Gamer
{
public int Id {get;set;}
}
and then your code, you would create a List<Gamer> from the DataTable or from Data Access you can directly return List<Gamer>.
Your method code would look like this if you follow the first approach:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Hope it helps.
You can use several options but the easiest one
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt.DefaultView.ToTable();
GridView1.DataBind();
Or you can use following function for dynamically create table from Query and then assign that to GridView
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        NorthwindEntities entity = new NorthwindEntities();
        var db1 = (from ordermst in entity.Orders
                    where ordermst.ShipCountry.Equals("Finland")
                    select new
                    {
                        CustomerID = ordermst.CustomerID,
                        OrderID = ordermst.OrderID
                    }).Take(10).ToList();
        DataTable dt = ConvertToDataTable(db1);
        GvOrder.DataSource = dt;
        GvOrder.DataBind();
 
        DataTable dt1 = new DataTable();
        dt1 = GvOrder.DataSource as DataTable;
        GvOrder1.DataSource = dt1;
        GvOrder1.DataBind();
 
    }
}
 
private DataTable ConvertToDataTable<T>(IList<T> data)
{
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    foreach (PropertyDescriptor prop in properties)
    {
        table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
    }
    foreach (T item in data)
    {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
        {
            row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        }
        table.Rows.Add(row);
    }
    return table;
}
Strangely enough to make it work all you need is to put an empty eventhandler.
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{}

Perform search in 3tier architecture

i am all confused in 3 tier
without using 3 tier this function worked
DataTable dt;
private void textBox1_TextChanged(object sender, EventArgs e)
{
DataView dv = new DataView(dt);
dv.RowFilter = string.Format("emp_f_name LIKE '%{0}%'",textBox1.Text);
dataGridView1.DataSource = dv;
}
BUt in 3 tier
i am all confused can u guys help me rewrite the code i am trying to search firstname in a textbox
in my bll class
public DataTable Display(string fname)
{
try
{
return obj.Display(fname);
}
catch (Exception ex)
{
throw ex;
}
}
in my dal class
public DataTable Display(string fname)
{
string query2;
OpenCnn();
query2 = "SELECT * FROM cntc_employee where fname='" +fname + "' ";
sda = new SqlDataAdapter(query2, con);
dt = new DataTable();
sda.Fill(dt);
CloseCnn();
return dt;
}
in ui class
private void textBox1_TextChanged(object sender, EventArgs e)
{
string fname = txtfname.Text;
DataView dv = new DataView(dt);
dt = obj.Display(fname);
dv.RowFilter = string.Format("emp_f_name LIKE '%{0}%'", textBox1.Text);
dataGridView1.DataSource = dv;
this.dataGridView1.DataSource = obj.Display(this.txtfname.Text);
}
Is this what you want?
Your BLL class should be like this
public DataTable Display(string fname)
{
try
{
DataTable dt = obj.Display(fname);//call to DAL
DataView dv = new DataView(dt);
dv.RowFilter = string.Format("emp_f_name LIKE '%{0}%'",
textBox1.Text);
return dv.ToTable();
}
catch (Exception ex)
{
throw ex;
}
}
In your UI
private void textBox1_TextChanged(object sender, EventArgs e)
{
string fname = txtfname.Text;
dt = obj.Display(fname);// Call to BLL
dataGridView1.DataSource = dt;
}
in your DAL class
public DataTable Display(string fname)
{
string query2;
OpenCnn();
query2 = "SELECT * FROM cntc_employee where fname='" +fname + "' ";
sda = new SqlDataAdapter(query2, con);
dt = new DataTable();
sda.Fill(dt);
CloseCnn();
return dt;
}

Sorting column in a GridView

Below is my code C# net4 for sorting column in GridView but I've this error:
CS1502: The best overloaded method match for System.Data.DataView.DataView(System.Data.DataTable) has some invalid arguments
in this line why?: DataView sortedView = new DataView(GridViewBind());
public SortDirection dir
{
get
{
if (ViewState["dirState"] == null)
{
ViewState["dirState"] = SortDirection.Ascending;
}
return (SortDirection)ViewState["dirState"];
}
set
{
ViewState["dirState"] = value;
}
}
protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
{
string sortingDirection = string.Empty;
if (dir == SortDirection.Ascending)
{
dir = SortDirection.Descending;
sortingDirection = "Desc";
}
else
{
dir = SortDirection.Ascending;
sortingDirection = "Asc";
}
DataView sortedView = new DataView(GridViewBind());
sortedView.Sort = e.SortExpression + " " + sortingDirection;
GridView1.DataSource = sortedView;
GridView1.DataBind();
}
public void GridViewBind()
{
sql1 = " SELECT * FROM `tbl` ORDER BY empid DESC; ";
dadapter = new OdbcDataAdapter(sql1, myConnectionString);
dset = new DataSet();
dset.Clear();
dadapter.Fill(dset);
GridView1.DataSource = dset.Tables[0];
GridView1.DataBind();
dadapter.Dispose();
dadapter = null;
myConnectionString.Close();
}
The error is due to this line
DataView sortedView = new DataView(GridViewBind());
The function GridViewBind() return type is void which is incorrect. It should return a DataTable.
If it returns DataTable then your code will work.
You need to modify your function as follow
public DataTable GridViewBind()
{
sql1 = " SELECT * FROM `tbl` ORDER BY empid DESC; ";
dadapter = new OdbcDataAdapter(sql1, myConnectionString);
dset = new DataSet();
dset.Clear();
dadapter.Fill(dset);
DataTable dt=dset.Tables[0];
GridView1.DataSource = dt;
GridView1.DataBind();
dadapter.Dispose();
dadapter = null;
myConnectionString.Close();
return dt;
}
Use DataView to sot the data.
public void GridViewBind()
{
sql1 = " SELECT * FROM `tbl` ORDER BY empid DESC; ";
dadapter = new OdbcDataAdapter(sql1, myConnectionString);
dset = new DataSet();
dset.Clear();
dadapter.Fill(dset);
DataTable dt = new DataTable();
dt=dset.Tables[0];
DataView dv = dt.DefaultView;
dv.Sort = "empid desc";
DataTable sortedDT = dv.ToTable();
GridView1.DataSource = sortedDT;
GridView1.DataBind();
dadapter.Dispose();
dadapter = null;
myConnectionString.Close();
}

Keep GridView sorted after index change

I got my gridview and I run the event sorting on header click , like this:
protected void GridViewFoundations_Sorting1(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GridViewFoundations.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridViewFoundations.DataSource = dataView;
GridViewFoundations.DataBind();
}
}
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;
}
Now I've two problems :
1) I click on the column header but it only shorts as "ASC" can anyone tell me why ?
2) How can i keep the sorting even when client change pages?
Bind grid function (i have some filters)
protected void BindGridFilters()
{
if (tb_fondeName.Text != "" && tb_fondeId.Text == "")
{
string sqlConnectString = ConfigurationManager.ConnectionStrings["umbracoDbDSN"].ToString();
string sqlSelect = "SELECT cmsDocument.nodeId,text, Max(updateDate) as UpdateDate from cmsContentXml,cmsDocument,cmsContent where cmsContent.nodeId=cmsContentXml.nodeId and cmsDocument.nodeId=cmsContent.nodeId and templateId=3094 and text like '%" + tb_fondeName.Text + "%' group by cmsDocument.nodeId,text";
SqlConnection sqlConnection = new SqlConnection(sqlConnectString);
SqlCommand sqlCommand = new SqlCommand(sqlSelect, sqlConnection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCommand);
DataTable sqlDt = new DataTable();
sqlDa.Fill(sqlDt);
GridViewFoundations.DataSource = sqlDt;
GridViewFoundations.DataBind();
}
if (tb_fondeId.Text != "" && tb_fondeName.Text == "")
{
string sqlConnectString = ConfigurationManager.ConnectionStrings["umbracoDbDSN"].ToString();
string sqlSelect = "SELECT cmsDocument.nodeId,text, Max(updateDate) as UpdateDate from cmsContentXml,cmsDocument,cmsContent where cmsContent.nodeId=cmsContentXml.nodeId and cmsDocument.nodeId=cmsContent.nodeId and templateId=3094 and cmsDocument.nodeId = " + Convert.ToInt32(tb_fondeId.Text) + " group by cmsDocument.nodeId,text";
SqlConnection sqlConnection = new SqlConnection(sqlConnectString);
SqlCommand sqlCommand = new SqlCommand(sqlSelect, sqlConnection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCommand);
DataTable sqlDt = new DataTable();
sqlDa.Fill(sqlDt);
GridViewFoundations.DataSource = sqlDt;
GridViewFoundations.DataBind();
}
if (tb_fondeId.Text != "" && tb_fondeName.Text != "")
{
string sqlConnectString = ConfigurationManager.ConnectionStrings["umbracoDbDSN"].ToString();
string sqlSelect = "SELECT cmsDocument.nodeId,text, Max(updateDate) as UpdateDate from cmsContentXml,cmsDocument,cmsContent where cmsContent.nodeId=cmsContentXml.nodeId and cmsDocument.nodeId=cmsContent.nodeId and templateId=3094 and cmsDocument.nodeId = " + Convert.ToInt32(tb_fondeId.Text) + " and text like '%" + tb_fondeName.Text + "%' group by cmsDocument.nodeId,text";
SqlConnection sqlConnection = new SqlConnection(sqlConnectString);
SqlCommand sqlCommand = new SqlCommand(sqlSelect, sqlConnection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCommand);
DataTable sqlDt = new DataTable();
sqlDa.Fill(sqlDt);
GridViewFoundations.DataSource = sqlDt;
GridViewFoundations.DataBind();
}
if (tb_fondeName.Text == "" && tb_fondeId.Text == "")
{
BindData();
}
}
Create a property GridSortDirection
protected string GridSortDirection
{
get
{
if (ViewState["GridSortDirection"] != null)
{
return Convert.ToString(ViewState["GridSortDirection"]);
}
else
{
return string.Empty;
}
}
set
{
ViewState["GridSortDirection"] = value;
}
}
On page load provide a default sort direction
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.GridSortDirection= "ASC";// setting default value
}
}
now before providing datasource to grid and binding the grid, add following lines and bind like this
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCommand);
DataTable sqlDt = new DataTable();
sqlDa.Fill(sqlDt);
//added 2 lines
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(GridSortDirection);
GridViewFoundations.DataSource = dataView;
GridViewFoundations.DataBind();
And now to change sort direction create a function
private string ChangeSortDirection(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "DESC";
break;
case SortDirection.Descending:
newSortDirection = "ASC";
break;
}
return newSortDirection;
}
And call this function in GridViewFoundations_Sorting1 like this
protected void GridViewFoundations_Sorting1(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GridViewFoundations.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
this.GridSortDirection=ChangeSortDirection(e.SortDirection);
dataView.Sort = e.SortExpression + " " + GridSortDirection;
GridViewFoundations.DataSource = dataView;
GridViewFoundations.DataBind();
}
}

sorting on searched records not working

I am having problem in sorting the searched records in a gridview to ascending and descending directions. I have applied the following code to normal gridview (all records) and it is working all fine but when I try to search any records from all records, and try to sort those searched records, following code neither performs any actions nor throws any errors: Following code is applied for sorting:
protected void GridView2_Sorting(object sender, GridViewSortEventArgs e)
{
string sortExpression = e.SortExpression;
if (GridViewSortDirection == SortDirection.Ascending)
{
GridViewSortDirection = SortDirection.Descending;
SortGridView1(sortExpression, DESCENDING);
}
else
{
GridViewSortDirection = SortDirection.Ascending;
SortGridView1(sortExpression, ASCENDING);
}
}
private void SortGridView1(string sortExpression, string direction)
{
DataTable dt = SearchTable().Tables[0];
DataView dv = new DataView(dt);
dv.Sort = sortExpression + direction;
GridView2.DataSource = dv;
GridView2.DataBind();
}
Search function code is:
public DataSet SearchTable()
{
string sql1 = "SELECT * from dbo.Documents1";
bool flag = false;
if (!txtRef.Text.Equals(""))
{
if (flag == false)
{
sql1 = sql1 + " where Ref LIKE N'%" + txtRef.Text + "%'";
flag = true;
}
else
{
sql1 = sql1 + " and Ref LIKE N'%" + txtRef.Text + "%'";
}
}
if (!txtSubject.Text.Equals(""))
{
if (flag == false)
{
sql1 = sql1 + " where Subject LIKE N'%" + txtSubject.Text + "%'";
flag = true;
}
else
{
sql1 = sql1 + " and Subject LIKE N'%" + txtSubject.Text + "%'";
}
}
}
using (SqlConnection con = new SqlConnection("Data Source=MEHDI-PC\\SQLEXPRESS;Initial Catalog=PIMS;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = sql1 + ";";
//cmd.CommandType = CommandType.StoredProcedure;
con.Open();
//dataset object to get all select statement results
DataSet ds = new DataSet();
//sql dataadoptor to fill dataset
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
adp.Fill(ds);
}
if (con.State == ConnectionState.Open)
{
con.Close();
}
return ds;
}
}
}
PageLoad Event function is:
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataSource = rpt.Documents1s.ToList();
GridView1.DataBind();
if (!IsPostBack)
{
BindGrid();
MultiView1.SetActiveView(vHome);
btnBacktoHome.Visible = false;
lblStatus.Visible = false;
}
}
I cant understand where I am going wrong. when clicked on a column to sort, it took me out of searched records and sorted "All-Records" which are placed in GridView1 while searched-records are placed in GridView2 as shown in the code. what I am failed to understand is, why programs jumps to GridView1 and sort all-records there when I click to click to sort searched-records in GridView2. Any help will be much appreciated. Thanks in advance.
Did you use the gridview binding code in inside of !ISPostBack ? like
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
//Grid Binding code
}
}
Edit for you page load code(Must add the databind in inside of !IsPostBack)
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = rpt.Documents1s.ToList();
GridView1.DataBind();
BindGrid();
MultiView1.SetActiveView(vHome);
btnBacktoHome.Visible = false;
lblStatus.Visible = false;
}
}

Categories