I have a gridview that is bound to a sqldatasource. The Gridview only has a pagesize of 10 and I would like each page to have 10 rows. Therefore if only 5 data rows exist then I would like to add an additional 5 empty rows. Is this easy to do?
Fill your data into data set and count the number of rows retrieved then fill the remaining to the dataset with empty dataRows try this:
Suppose you have a DataSet dt filled with the table or data you want
int remainingRows=10 - dt.Rows.Count;
DataRow dr;
for (int i = 0; i < remainingRows; i++)
{
dr = dt.NewRow();
dr[0] = dr[1] = dr[2] = dr[3] = dr[4] = "";//index goes the no of cols in the table
dt.Rows.Add(dr);
}
dt.AcceptChanges();
grdView.DataSource = dt;
grdView.DataBind();
You can see this
For meeting your requirement , I think you shouldn't use sqldatasource to bind gridview instead of manual binding the datasource to gridview. you can encapsulate a datatable or dataview which each page have 10 rows as the datasource.
Related
I have been working on this gridview project for a few days and have been able to make some progress. Where I am having difficulty is after sorting the gridview which works fine, I want to take the selected rows from my gridview and place those selected rows into a repeater control. I have been looking here for people with the same issue and have tried using viewstate but I continue to only get the default sort order into the repeater control. Example row 0 is selected with the name john smith after sort I have jane doe at row 0 but when selecting row 0 and jane doe I get john smith in the repeater control. I know that this has to be something simple but I have tried many things with not luck.
This is my sort code which works.
protected void GridView1_Sorting1(object sender, GridViewSortEventArgs e)
{
DataTable dtrslt = (DataTable)ViewState["dirState"];
if (dtrslt.Rows.Count > 0)
{
if (Convert.ToString(ViewState["sortdr"]) == "Asc")
{
dtrslt.DefaultView.Sort = e.SortExpression + " Desc";
ViewState["sortdr"] = "Desc";
}
else
{
dtrslt.DefaultView.Sort = e.SortExpression + " Asc";
ViewState["sortdr"] = "Asc";
}
ViewState["sortexp"] = e.SortExpression; //resort and store.
ViewState["dirState"] = dtrslt;
GridView1.DataSource = dtrslt;
GridView1.DataBind();
}
}
Now I have a button that will copy the data from the first datatable to a new datatable which only contains the selected rows. I am sure that I am having the computer do more work than it should but I was trying everything.
This code below is copying the data into the new datatable and binding to the repeater control. Works fine if I don't sort the gridview. Please let me know your thoughts or if I need to provide additional information.
protected void CopyToDataTable(object sender, EventArgs e)
{
//Create a new DataTable.
DataTable dtNotary = new DataTable();
DataTable dtrslt = (DataTable)ViewState["dirState"];
dtNotary = dtrslt.Clone();
DataRow dr = dtrslt.Rows[0];
//Loop through the GridView and copy rows.
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox ckBox = (CheckBox)gRow.FindControl("notaryselect");
if (ckBox.Checked)
{
dr = dtrslt.Rows[gRow.RowIndex];
dtNotary.ImportRow(dr);
}
}
RepeaterNotary.DataSource = dtNotary
RepeaterNotary.DataBind();
}
Ok, keep in mind that you using the "default" view.
that means the table (and hence row index INTO that table will not match) after you sort.
So, when you use a "data view", it does NOT effect nor change the order of hte base table.
So, this:
DataTable rstData = new DataTable();
rstData = General.MyRst("SELECT ID, HotelName FROM tblHotelsA");
for (int i = 0; i < rstData.Rows.Count; i++)
{
Debug.Print($"{rstData.Rows[i]["ID"].ToString()} H= {rstData.Rows[i]["HotelName"]}");
}
// now sort table by id REVERSE order!
rstData.DefaultView.Sort = "ID DESC";
for (int i = 0; i < rstData.Rows.Count; i++)
{
Debug.Print($"{rstData.Rows[i]["ID"].ToString()} H= {rstData.Rows[i]["HotelName"]}");
}
Debug.Print("---- sorted output");
foreach(DataRowView OneRow in rstData.DefaultView)
{
Debug.Print($"{OneRow["ID"].ToString()} H= {OneRow["HotelName"]}");
}
Output:
1 H = My Cool
2 H = Ramada Lodge
3 H = Sandman Inn
4 H = Super 8
5 H = Inns of Banff
6 H = Swiss Village
7 H = Mary's Motel
16 H = Batman's Cave
1 H = My Cool
2 H = Ramada Lodge
3 H = Sandman Inn
4 H = Super 8
5 H = Inns of Banff
6 H = Swiss Village
7 H = Mary's Motel
16 H = Batman's Cave
---- sorted output
16 H = Batman's Cave
7 H = Mary's Motel
6 H = Swiss Village
5 H = Inns of Banff
4 H = Super 8
3 H = Sandman Inn
2 H = Ramada Lodge
1 H = My Cool
NOTE VERY close - after I sorted the "data view", the table order DOES not change when I reference the rows!!!!
Only the 3rd run shows the data sorted. And you could do say this:
Debug.Print("---- sorted output example 2");
DataTable dt2 = rstData.DefaultView.ToTable();
for (int i = 0; i < dt2.Rows.Count; i++)
{
Debug.Print($"{dt2.Rows[i]["ID"].ToString()} H= {dt2.Rows[i]["HotelName"]}");
}
So, in above, I used the "totable()" to get a real sorted view!
Now, lets check the results of that table in the grid view.
this will show this even better:
DataTable rstData = new DataTable();
rstData = General.MyRst("SELECT ID, HotelName FROM tblHotelsA");
// now sort table by id REVERSE order!
rstData.DefaultView.Sort = "ID DESC";
GridView1.DataSource = rstData;
GridView1.DataBind();
foreach (GridViewRow gRow in GridView1.Rows)
{
Debug.Print($"Grid row {gRow.RowIndex} First GV ID = {gRow.Cells[0].Text} First Table row ID = {rstData.Rows[gRow.RowIndex]["ID"]}");
}
Output:
Grid row 0 First GV ID = 16 First Table row ID = 1
Grid row 1 First GV ID = 7 First Table row ID = 2
Grid row 2 First GV ID = 6 First Table row ID = 3
Grid row 3 First GV ID = 5 First Table row ID = 4
Grid row 4 First GV ID = 4 First Table row ID = 5
Grid row 5 First GV ID = 3 First Table row ID = 6
Grid row 6 First GV ID = 2 First Table row ID = 7
Grid row 7 First GV ID = 1 First Table row ID = 16
So, once again, you can see the "default" view is used by the GV, but the base table is still not sorted.
I tend to NOT use the built in "default" data view, since you can wind up with the above confusing. thus, a lot of my code feeds the "data view" to the table, and not the "default view". I do this "only" to reduce confusing.
eg this code is common:
Dim rstGridData As DataTable
rstGridData = MyrstP(cmdSQL)
Dim dView As DataView = rstGridData.DefaultView
dView.RowFilter = strWhere
dView.Sort = "QuoteDate DESC, ID DESC"
Me.ListView1.DataSource = rstBlank
Note HOW I send the data view to the gridview/lv in above.
Ok, I (probably spent too much time on above - my sorry!!).
So, next up:
I would actually re-pull the data based on the PK settings. both GV, and LV have what is called "data keys", and it is a great collection of the PK row "id", and even better is NEVER exposed to the client side browser (good for security - people can't mess with your pk's in the markup!!!).
And also, keep in mind for most cases, re-pulling the data will cost LESS then persisting the data table in viewstate!!!
So, I would say suggest using this:
string MyIdList = "";
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox ckBox = (CheckBox)gRow.FindControl("chkActive");
if (ckBox.Checked)
{
if (MyIdList != "")
MyIdList += ",";
MyIdList += GridView1.DataKeys[gRow.RowIndex]["ID"].ToString();
}
}
DataView MyView = rstData.DefaultView;
MyView.RowFilter = $"ID IN({MyIdList})";
Repeater1.DataSource = MyView;
Repeater1.DataBind();
In other words, operate by PK database ID (assuming you have one).
So, in the gv define, you need to set the datakeys "ID" (column name) of the PK value.
eg:
<asp:GridView ID="GridView1" runat="server" CssClass="table"
DataKeyNames="ID" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
etc.
So, datakeys is nice, since then based on GV row, you can always get/have use of the database PK row id, we don't care about order, and even better is the PK row idea does not have to be exposed nor included in the markup.
int Row=0;
Row = PurchaseGridView.Rows.Count;
PurchaseGridView.Rows[Row].Cells[0].Text = ProductNameDropDown.SelectedValue.ToString();
PurchaseGridView.Rows[Row].Cells[1].Text = ProductNameDropDown.SelectedIndex.ToString();
PurchaseGridView.Rows[Row].Cells[2].Text = ProductPriceTxtBox.Text;
PurchaseGridView.Rows[Row].Cells[3].Text = QuantityTxtBox.Text;
PurchaseGridView.Rows[Row].Cells[4].Text = NetPriceTxtBox.Text;
i am adding values of textboxes in gridview like above, but it gives error.
Error: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
You have a few fundamental errors in your code:
You are using the Count to point to a new index which doesn't exists and thus you are getting the index out of range.
You cannot add rows to an asp.net gridview directly. You have to do it through a data binding. Here is an example:
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("ProductNameSelectedValue", typeof(string));
DataColumn dc = new DataColumn("ProductNameSelectedIndex", typeof(int));
..
Rest of you columns
..
DataRow dr = dt.NewRow();
dr["ProductNameSelectedValue"] = ProductNameDropDown.SelectedValue.ToString();
dr["ProductNameSelectedIndex"] = ProductNameDropDown.SelectedIndex;
..
Assign the rest of the columns
..
dt.Rows.Add(dr);
gv.DataSource = dt;
gv.DataBind();
DataTable dtbind = new DataTable();
dtbind = objvehicleBAL.GetTaxdetails();
for (int i = 0; i < dtbind.Rows.Count; i++)
{
DateTime dt1 = DateTime.ParseExact(dtbind.Rows[i]["todate"].ToString(), "dd/MM/yyyy", null);
if (dt1 < ((DateTime.Now.AddDays(15))))
{
GVTax.DataSource = dtbind.Rows[i];
GVTax.DataBind();
}
}
I had written my conditions in if(). I want to bind only satisfied rows in grid. How can I write this?
You do not need to bind the Grid in loop on the Row of data table rather filter the DataTable by the condition you want and bind it once. You can get DataView from the data table and use its property DataView.RowFilter to apply the date filter.
dtbind = objvehicleBAL.GetTaxdetails(); //Filter the record in GetTaxdetails
DataView dv = dtbind.DefaultView; //or use DataView with RowFilter
dv .RowFilter = "todate = #" + DateTime.Now.AddDays(15).ToString() + "#";
GVTax.DataSource = dv;
GVTax.DataBind();
DataTable dtbind1 = objvehicleBAL.GetTaxdetails();
DataTable dtbind2 = new DataTable();
foreach (DataRow row in dtbind1.Rows)
{
DateTime dt1 = DateTime.ParseExact(row["todate"].ToString(), "dd/MM/yyyy", null);
if (dt1 < ((DateTime.Now.AddDays(15))))
dtbind2.Rows.Add(row);
}
}
GVTax.DataSource = dtbind2;
GVTax.DataBind();
No need to bind each row and call DataBind mehtod each time.
Just use the following:
protected void BindGrid()
{
DataTable dtbind = new DataTable();
dtbind=objvehicleBAL.GetTaxdetails();//get the rows filtered in SQL
if(dtbind!=null && dtbind.Rows.Count>0)//always check for null for preventing exception
{
GVTax.DataSource = dtbind;
}
GVTax.DataBind();
}
Hope this helps you!
You can use the Select method of DataTable along with a filtering expression, to get the rows which match your criteria. Then, bind it to to your GridView.
string filterExp = "todate < dateadd(day,15,getdate())";
var filtered = dtBind.Select(filterExp);
GVTax.DataSource = filtered ;
GVTax.DataBind();
You can create another datatable and fill the rows satisfying your condition in the second datatable and bind your gridview with second datatable (having filtered rows)
dttableNew = dttableOld.Clone();
foreach (DataRow drtableOld in dttableOld.Rows)
{
if (/*put some Condition */)
{
dtTableNew.ImportRow(drtableOld);
}
}
GVTax.DataSource = dtTableNew;
GVTax.DataBind();
Im trying to get the values from each column in a single row to equal a total. Here is the code that im using to achieve this in c# asp.net
DataTable dt = ds.Tables.Add("InspireTable");
string pass = (String)Session["name"];
if (pass.Equals("High"))
{
dt.Columns.Add("Inspire", typeof(string));
dt.Columns.Add("SNS", typeof(int));
dt.Columns.Add("TT", typeof(int));
dt.Columns.Add("Music", typeof(int));
dt.Columns.Add("Total", typeof(string));
DataRow row = dt.NewRow();
row["Inspire"] = "Score";
row["SNS"] = 10;
row["TT"] = 10;
row["Music"] = 0;
dt.Rows.Add(row);
Chart1.DataSource = dt;
this.GridView1.Visible = true;
GridView1.DataSource = dt;
GridView1.DataBind();
}
Any ideas? I have tried calling each column and adding them but that seem not to work.
With the old DataTable.Compute method, for example:
int snsTotal = (int) dt.Compute("SUM(SNS)", null); // the second argument is the filter
Here's the "modern" Linq approach:
int snsTotal = dt.AsEnumerable().Sum(r => r.Field<int>("SNS"));
Edit: it seems as if you want to sum the numeric values of each row into a "total"-column. Then you can use a Column-Expression:
dt.Columns.Add("Total", typeof(int), "SNS + TT + Music");
I want to search some data from DataTable to show in GridView.
Like
(select * from customer where id="1")
Can I do that?
DataRow[] foundRows = yourTable.Select("id=1");
Or you can filter rows in default view:
yourTable.DefaultView.RowFilter = "id = 1";
GridView gv = new GridView();
gv.DataSourse = yourTable.DefaultView
gv.DataBind()