Sort GridView by column name - c#

I am making a GridView and assigning it to the View property of a ListView. The ListView's ItemsSource is bound to an ObservableCollection<Entry>. Entry is a model in my MVVM application, and it contains a List<KeyValuePair<string,string>>. It also has an indexer which fetches the first KeyValurPair<string,string>'s Value property (from the list) which matches the indexer parameter. So it's much like a dictionary.
Now here's how I am making the GridView.
foreach (Column column in category.Columns.Where(c => c.IsVisibleInTable)) {
var gridViewColumn = new GridViewColumn {
Header = column.Name,
DisplayMemberBinding = new Binding($"[{column.Name}].Value")
};
gridView.Columns.Add(gridViewColumn);
}
Column is also a model but that's not really relevant here.
Now I want to tell the GridView to sort based on the first column. But I can't use the DefaultView of the ItemsSource and add a SortDescription to it because SortDescription expects a Property name whereas I am not binding to a property name but instead to an indexer.
So how can I sort based on the second column?

here is sorting algo
iN gridview pass this two parameter aspx
AllowSorting="true"
OnSorting="OnSorting"
private string SortDirection
{
get { return ViewState["SortDirection"] != null ? ViewState["SortDirection"].ToString() : "ASC"; }
set { ViewState["SortDirection"] = value; }
}
protected void OnSorting(object sender, GridViewSortEventArgs e)
{
this.BindGrid(e.SortExpression);
}
here we have to place the code
` private void BindGrid(string sortExpression = null)
{
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * from [test].[dbo].[myform] order by name", conn);
SqlDataAdapter sda = new SqlDataAdapter();
cmd.Connection = conn;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
if (sortExpression != null)
{
DataView dv = dt.AsDataView();
this.SortDirection = this.SortDirection == "ASC" ? "DESC" : "ASC";
dv.Sort = sortExpression + " " + this.SortDirection;
GridView2.DataSource = dv;
}
else
{
GridView2.DataSource = dt;
}
GridView2.DataBind();
conn.Close();
}
}`

Related

Making a DataGridViewColumn sortable

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.

Manual Grid View Sorting

My Grid View is manually data bound (for other things to work). Reading other threads I have to manage my own sorting events.
When clicking a column to sort it on my webpage I get the error:
"Object reference not set to an instance of an object."
The result of this was that table was null, but I cannot see why it is null.
Any ideas?
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable table = GetData();
table.DefaultView.Sort = e.SortExpression + " " + SetSortDirection(e.SortDirection.ToString());
GridView1.DataSource = table;
GridView1.DataBind();
}
.
protected string SetSortDirection(string currentsortDirection)
{
string sortDirection;
if (currentsortDirection == "Ascending")
{
sortDirection = "Descending";
}
else
{
sortDirection = "Ascending";
}
return sortDirection;
}
EDIT:
public DataTable GetData()
{
SqlConnection conn = new SqlConnection(#"Data Source=.\SQLEXPRESS;Initial Catalog=DatabaseName;Integrated Security=True");
conn.Open();
string query = "SELECT * FROM tablex WHERE Property='" + Request.QueryString["xxx"] + "'";
SqlCommand cmd = new SqlCommand(query, conn);
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
return dt;
}
Thanks.
DataTable table = BuildInfo_GridView.DataSource as DataTable;
like this u won't get the datasource what u already binded call back end query to get tha datatable or when u r binding the data only store it in view state and get it
Save your sort order in view state
if (ViewState["sortOrder"] != null)
{
ViewState["sortExpression"] = e.SortExpression;
if (ViewState["sortOrder"].ToString().ToUpper() == "ASCENDING")
{
e.SortDirection = SortDirection.Descending;
ViewState["sortOrder"] = SortDirection.Descending.ToString();
}
else
{
e.SortDirection = SortDirection.Ascending;
ViewState["sortOrder"] = SortDirection.Ascending.ToString();
}
}
else
{
ViewState["sortExpression"] = e.SortExpression;
ViewState["sortOrder"] = e.SortDirection.ToString();
}

Populate dropdownlist inside a gridview

I have a Dropdownlist in a Gridview and i have to show the records associated with every id.And the ID contains more than 10 records so how can i show them??
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
con.Open();
var ddl = (DropDownList)e.Row.FindControl("DropDownList1");
//int CountryId = Convert.ToInt32(e.Row.Cells[0].Text);
SqlCommand cmd = new SqlCommand("select LastName from Profile_Master", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
con.Close();
ddl.DataSource = ds;
ddl.DataTextField = "LastName";
ddl.DataBind();
}
}
FillSelect(myDropDownList, "--select--", "0", true);
public static void FillSelect(DropDownList DropDown, string SelectItemText, string SelectItemValue, bool includeselectitem)
{
List<PhoneContact> obj_PhoneContactlist = getAll();
if (obj_PhoneContactlist != null && obj_PhoneContactlist.Count > 0)
{
DropDown.DataTextField = "PhoneContactName";
DropDown.DataValueField = "id";
DropDown.DataSource = obj_PhoneContactlist.OrderBy(o => o.PhoneContactName);//linq statement
DropDown.DataBind();
if (includeselectitem)
DropDown.Items.Insert(0, new ListItem(SelectItemText, SelectItemValue));
}
}
public static List<PhoneContact> getAll()
{
obj_PhoneContactlist = new List<PhoneContact>();
string QueryString;
QueryString = System.Configuration.ConfigurationManager.ConnectionStrings["Admin_raghuConnectionString1"].ToString();
obj_SqlConnection = new SqlConnection(QueryString);
obj_SqlCommand = new SqlCommand("spS_GetMyContacts");
obj_SqlCommand.CommandType = CommandType.StoredProcedure;
obj_SqlConnection.Open();
obj_SqlCommand.Connection = obj_SqlConnection;
SqlDataReader obj_result = null;
obj_SqlCommand.CommandText = "spS_GetMyContacts";
obj_result = obj_SqlCommand.ExecuteReader();
//here read the individual objects first and append them to the listobject so this we get all the rows in one list object
using (obj_result)
{
while (obj_result.Read())
{
obj_PhoneContact = new PhoneContact();
obj_PhoneContact.PhoneContactName = Convert.ToString(obj_result["PhoneContactName"]).TrimEnd();
obj_PhoneContact.PhoneContactNumber = Convert.ToInt64(obj_result["PhoneContactNumber"]);
obj_PhoneContact.id = Convert.ToInt64(obj_result["id"]);
obj_PhoneContactlist.Add(obj_PhoneContact);
}
}
return obj_PhoneContactlist;
}
I have done this to get my phonecontacts which are in the data base into dropdown you can change the stored procedures and the values according to your need.
Hope this helps:D
We just ran into this issue where I work. Our way around this problem was to first get the DropDownLists UniqueID. This is basically a Client ID. Inside of that ID is a reference to the row of the GridView that it was selected from. THE ONLY PROBLEM is that it seems to add 2 to the row count. So if you select Row 1's DropdownList, the Unique ID will bring you a reference to the 3rd row. So:
Get the unique ID > Split it however you need to to get the row > use the row number to get the values you need.

Gridview sorting in ASP.NET

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

Code to create Sorting for a GridView in ASP.net in Code Behind?

This is my code code for the Page_Load Event
OdbcConnection myConnection;
DataSet dataSet = new DataSet();
OdbcDataAdapter adapter;
//making my connection
myConnection = new OdbcConnection(ConfigurationManager.ConnectionStrings ["ODBC_ConnectionString"].ConnectionString);
adapter = new OdbcDataAdapter("SELECT * from Company", myConnection);
adapter.Fill(dataSet, "MyData");
GridView1.DataSource = dataSet;
Session["DataSource"] = dataSet;
GridView1.DataBind();
This is my code for the PageIndexChanging event and it all works fine.
DataSet ds = new DataSet();
if (Session["DataSource"] != null)
ds = ((DataSet)Session["DataSource"]);
GridView1.DataSource = ds;
GridView1.PageIndex = e.NewPageIndex;
this.GridView1.DataBind();
Now what code do i need to create the Sorting event?
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
?????????????????????????
}
Etienne
I usually do this:
public string SortField {
get {
return (string) ViewState["_sortField"];
}
set {
ViewState["_sortField"] = value;
}
}
public string SortDir {
get {
return (string) ViewState["_sortDir"];
}
set {
ViewState["_sortDir"] = value;
}
}
Put your code to do databinding into another Method because you have to call it during Sort, Paging, and when your page first loads. Call it DoDataBind() for example. Then you have in DoDataBind()
DataTable dt = yourDataSet.Tables[0];
dt.DefaultView.Sort = SortField + " " + SortDir;
GridView1.DataSource = dt.DefaultView;
GridView1.DataBind();
Then your event looks like this:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) {
if (e.SortExpression == SortField && SortDir != "desc") {
SortDir = "desc";
}
else {
SortDir = "asc";
}
SortField = e.SortExpression;
DoDataBind();
}
Then in your aspx page you'll need to specify what the SortExpression is. For example something like this:
<asp:BoundField DataField="FIRSTNAME"
HeaderText="First Name" SortExpression="FIRSTNAME" />
You can filter and sort your dataset using:
ds.Tables[0].Select(filterExp, sortExp, etc...);

Categories

Resources