Binding a DataTable to Gridview - Doesn't display on Web Page - c#

The issue I'm having is getting my DataTable to display in the Gridview. I have searched the web for answers, but everything I have found relates to binding database information right after a query is executed. I have to manipulate the data that I get from the query to display an average so everything in my datatable is stored in local variables and containers. Here is the code for the gridview on the aspx page and the block that is adding my rows to the table and binding the table to the girdview. any help on why it isn't displaying on the web would be appreciated. I'm using VS2012 and .Net v4
DataRow newRow;
for (int i = 0; i < portcount; i++)
{
newRow = averageTable.NewRow();
newRow["port_num"] = i+1;
newRow["port_status"] = currentstat[i]; //this is a list<Int32>
newRow["average_uptime"] = (statusCalc[i] / counter) * 100;
//statusCalc is an int array
averageTable.Rows.Add(newRow);
}
statusRdr.Close();
GridView completeView = new GridView();
this.completeView.Visible = true;
completeView.DataSource = averageTable;
completeView.DataBind();
<asp:Content ID="bodyContnet" ContentPlaceHolderID="cphContent" runat="server">
<asp:GridView ID="completeView" runat="server" AutoGenerateColumns="False" ViewStateMode="Enabled" ForeColor="WhiteSmoke" Width="51%" Height="204px">
<Columns>
<asp:BoundField DataField="port_num" HeaderText="Port" />
<asp:BoundField DataField="port_status" HeaderText="Status" />
<asp:BoundField DataField="average_uptime" HeaderText="Average Uptime" />
</Columns>
</asp:GridView>
<br />
<br />
<asp:Label ID="message" runat="server" ForeColor="WhiteSmoke" Text="Port Status Table"></asp:Label>
</asp:Content>

You don't need to re-create the GridView, it's already on the page and visible by default. Remove the lines that do this so your code looks like this:
DataRow newRow;
for (int i = 0; i < portcount; i++)
{
newRow = averageTable.NewRow();
newRow["port_num"] = i+1;
newRow["port_status"] = currentstat[i]; //this is a list<Int32>
newRow["average_uptime"] = (statusCalc[i] / counter) * 100;
//statusCalc is an int array
averageTable.Rows.Add(newRow);
}
statusRdr.Close();
completeView.DataSource = averageTable;
completeView.DataBind();

Related

Auto Serial Number With Custom GridView Pagination

I am using custom pagination for the GridView along with Repeater. Here is the code that I've done so far:
Default.aspx:
<asp:Repeater ID="rptPager" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lnkPage" runat="server" Text='<%#Eval("Text") %>' CommandArgument='<%# Eval("Value") %>'
CssClass='<%# Convert.ToBoolean(Eval("Enabled")) ? "page_enabled" : "page_disabled" %>'
OnClick="lnkPage_Click" PostBackUrl='<%# "~/UI/SearchCity.aspx?page=" + Eval("Text") %>' OnClientClick='<%# !Convert.ToBoolean(Eval("Enabled")) ? "return false;" : "" %>'></asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Default.aspx.cs:
private void BindGridView(int pageIndex) //Bind data
{
List<Country> countryListView = null; //List type variable
countryListView = aManager.AllCountryList(); //Assigns the data in the list calling the method
totalRecordCount = countryListView.Count; //Counts total no. of record
pageSize = 4; //Page size
int startRow = pageIndex * pageSize; //Variable to assign the starting row
detailsGridView.DataSource = countryListView.Skip(startRow).Take(pageSize); //Shows data in GridView
detailsGridView.DataBind();
}
private void BindPager(int currentPageIndex) //Pagination
{
double getPageCount = (double)((decimal)totalRecordCount / (decimal)pageSize);
int pageCount = (int)Math.Ceiling(getPageCount); //Count page
List<ListItem> pages = new List<ListItem>(); //New list item
/****Pagination starts ****/
if (pageCount > 1)
{
pages.Add(new ListItem("<<", "1", currentPageIndex > 0));
for (int i = 1; i <= pageCount; i++)
{
pages.Add(new ListItem(i.ToString(), i.ToString(), i != currentPageIndex + 1));
}
pages.Add(new ListItem(">>", pageCount.ToString(), currentPageIndex < pageCount - 1));
}
/****Pagination ends ****/
rptPager.DataSource = pages;
rptPager.DataBind();
}
The above works perfect. But the issue is when I use the following to generate auto serial number, it does not work properly:
<%#(Container.DataItemIndex+1)%>
I mean when I browse to page 2, the row count begins from 1 and the same for other pages. Is there any way to resolve or any other efficient technique to handle this?
The Container.DataItemIndex is the index of the data item bound to the GridView and it can be used to determine the Row Index of the GridView Row. Therefore it is behaving as expected.
You have two choices:
1- Use your own rowcounter variable and store it in the session or viewpag objects.
2- better yet, let the database generate your row number instead. For example, if you are using Sql Server then do something like this:
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) ROW_NUM, * FROM MYTABLE
Here is the solution for the GridView custom pagination:
<asp:TemplateField HeaderText="Serial Number">
<ItemTemplate>
<%# (detailsGridView.PageIndex * detailsGridView.PageSize) + (Container.DataItemIndex + 1) %>
</ItemTemplate>
</asp:TemplateField>
This is best solution
<%# (Container.DataItemIndex + 1) %>

add textbox in DataTable aspx.net

i want to add textBox into dataTable row.I dont know how to do that.Is it possible to add textBox to a dataTable?First it give me this error:
Index was out of range. Must be non-negative and less than the size of
the collection. Parameter name: index
Here is my code:
Markup:
<asp:GridView ID="GridView2" runat="server" ShowHeader="false" OnRowDataBound="GridView2_RowDataBound">
<Columns>
<ItemTemplate >
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind:
private void AddNewRecordRowToGrid()
{
DataTable dt = new DataTable();
DataRow dr;
dt.TableName = "table";
dt.Columns.Add(new DataColumn("Zabeleshka", typeof(TextBox)));
dr = dt.NewRow();
dt.Rows.Add(dr);
ViewState["marks"] = dt;
if (ViewState["marks"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["marks"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
drCurrentRow["Zabeleshka"] = TextBox1.Text;
if (dtCurrentTable.Rows[0][0].ToString() == "")
{
dtCurrentTable.Rows[0].Delete();
dtCurrentTable.AcceptChanges();
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["marks"] = dtCurrentTable;
GridView2.DataSource = dtCurrentTable;
GridView2.DataBind();
}
}
}
}
You can add a textbox into a gridview no problem then find it from the code behind in the RowDataBound Grid Method. Your problem is more than likely the fact that you have closed your TemplateField and have not opened one. You need to add
<asp:TemplateField>
above your
<ItemTemplate>.
As your markup code i think you want Text Box inside Gridview with containing some value into that,
for this,
first of all your markup is not correct, the correct one is,
<asp:GridView ID="GridView2" runat="server" ShowHeader="false" OnRowDataBound="GridView2_RowDataBound">
<Columns>
<asp:TemplateField> <%-- you have not opened it in your markup --%>
<ItemTemplate >
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and in code behind,
to get the textbox value you need
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
edited,
in your code,
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBox1 = (TextBox)GridView2.Rows[0].FindControl("TextBox1");
drCurrentRow["Zabeleshka"] = TextBox1.Text;
the for loop condition is (i <= dtCurrentTable.Rows.Count)
you should try this (i < dtCurrentTable.Rows.Count)
because the counting of row is start from 0 and thats why you getting index out of range error.

Checkbox field not visible in gridview

I am working in asp.net. Trying to display data in gridview retrieved from a web service. I want five fields in gridview, one checkbox field and other four are values from service i.e.
CheckboxField,FirstName,LastName,OffenseName,FineAmount
1 ) Following is gridview code, that i just dragged and dropped into page
<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BackColor="#CCFF33" />
</asp:GridView>
2 ) Following is my method that i call, to create fields in a DataTable, which i will bind to gridview later.
DataTable table = new DataTable();
table.Columns.Add("Select", typeof(CheckBox)); // i think problem is here
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("OffenseName", typeof(string));
table.Columns.Add("FineAmount", typeof(string));
3) Following is code to that populates the data table, with data
for (int i = 0; i < noOfContacts; i++)
{
object[] rowVals = new object[5];
rowVals[0] = giveCheckBox(i); // this method is declared below, which gives me a checkbox with unique id
rowVals[1] = listOfContacts[i].FirstName;
rowVals[2] = listOfContacts[i].LastName;
rowVals[3] = listOfCharges[j].GHQOffenseId;
rowVals[4] = listOfCharges[j].GHQFineAmount;
table.Rows.Add(rowVals);
}
GridView1.DataSource = table;
GridView1.DataBind();
4) This is method that gives me a checkbox, with unique id
public CheckBox giveCheckBox(int i)
{
CheckBox chk = new CheckBox();
chk.ID = "chk_" + i;
chk.Text = "Pay";
return chk;
}
Problem is that when i run the program, it only display four fields but not first checkbox field. I want to dispay that must.
But if i add checkbox field in designing view, (click arrow on gridview, click Add New Fields), then it throws exception at binding line i.e.
GridView1.DataBind();
Please guide me how to make checkbox field visible.
You can insert all your fields in design like code below :
<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BackColor="#CCFF33" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chk_box" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="OffenseName" HeaderText="OffenseName" />
<asp:BoundField DataField="FineAmount" HeaderText="FineAmount" />
</Columns>
</asp:GridView>
and for the code behind:
DataTable table = new DataTable();
for (int i = 0; i < 2; i++)
{
DataRow dr = table.NewRow();
dr["FirstName"] = "Ahmed";
dr["LastName"] = "Ahmed";
dr["OffenseName"] = "Ahmed";
dr["FineAmount"] = "Ahmed";
table.Rows.Add(dr);
}
GridView1.DataSource = table;
GridView1.DataBind();
Instead adding the checkbox to your table(which is wrong anyway) add a template field to the gridview as below. Also specify AutoGenerateColumns=true. Then remove all the code in your codebehind which tries to add checkbox column to the table and gridview.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True">
<Columns>
<asp:TemplateField ShowHeader="False" >
<ItemTemplate>
<asp:CheckBox ID="checkBoxSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<HeaderStyle BackColor="#CCFF33" />
</Columns>
</asp:GridView>
Yes, you're right the problem lies exactly in that code snippet. Replace the following line
table.Columns.Add("Select", typeof(CheckBox));
with this one
table.Columns.Add("Select", typeof(bool));

Grid view row command is firing after every second click

I've shopping cart in grid view. The grid is in update panel with update mode always. The grid view is itself in a user control and this user control renders in a child page (GridView --> User Control --> Child aspx page --> master page). Whenever I click on any button to modify cart the gridview row command not fires first time but when I again click on the button second time the row command fires correctly. Now I don't know why the row command event is not firing on first click and it is firing only on every even click (second click).
ASP:
<asp:GridView ID="GVCart" runat="server" AutoGenerateColumns="False" OnRowCommand="CartUpdate">
<Columns>
<asp:BoundField DataField="Product_Name" HeaderText="Product Name">
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="Button3" runat="server" CommandArgument='<%# Eval("Product_ID") %>'
CommandName="DecreseCartQty" Height="20px" ToolTip="Minus" AlternateText="+" />
<asp:ImageButton ID="ImageButton1" runat="server" CommandArgument='<%# Eval("Product_ID") %>'
CommandName="IncreaseCartQty" Height="20px" ToolTip="Add" AlternateText="-" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="ABC" runat="server" Text='<%# Eval("ItemQTY")+" * "+Eval("Price")+" = "+Eval("TotalPrice") %> '></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="Button4" runat="server" CommandArgument='<%# Eval("Product_ID") %>' CommandName="Remove" ToolTip="Cancel"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#: (in user control)
protected void CartUpdate(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "IncreaseCartQty")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows[i]["ItemQTY"] = Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) + 1;
CartDT.Rows[i]["TotalPrice"] = Convert.ToInt32(CartDT.Rows[i]["Price"]) * Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
if (e.CommandName == "DecreseCartQty")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
if (Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) > 1)
{
CartDT.Rows[i]["ItemQTY"] = Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]) - 1;
CartDT.Rows[i]["TotalPrice"] = Convert.ToInt32(CartDT.Rows[i]["Price"]) * Convert.ToInt32(CartDT.Rows[i]["ItemQTY"]);
// Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
}
if (e.CommandName == "Remove")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows.RemoveAt(i);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
}
Can anyone tell me what wrong I am doing. Your answer will be great help for me.
Thanks in advance.
It is behaving properly. You should rebind the gridview after CartUpdate so that another post back is not required.
just add these lines after
if (e.CommandName == "Remove")
{
int ProductId = Convert.ToInt32(e.CommandArgument.ToString());
DataTable CartDT = (DataTable)Session["cart"];
for (int i = 0; i < CartDT.Rows.Count; i++)
{
if (CartDT.Rows[i]["Product_ID"].ToString() == ProductId.ToString())
{
CartDT.Rows.RemoveAt(i);
//Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
}
DataTable CartDT = (DataTable)Session["cart"];
gridview1.datasource=CartDT ;
gridview1.databind();
Checkout this answer, I think it will solve your problem. If you have your grid view in user control this issue can arise. I had a same issue when I had my grid view in a user control.

Adding a drop down in itemtemplate and populating value dynamically

I have an item template in a GridView and I want to create a dropdown for each row and bind it to a value retrieved from the database.. but I am not sure how to do this.. this is what i have so far.. but not sure where to put the code to populate the drop down per row..
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlMyQuantity" SelectedValue='<%#
(DataBinder.Eval(Container.DataItem,"Quantity")) %>'>
</asp:DropDownList>
</ItemTemplate>
and in code behind, not sure how to or where to put this so that it is created on every row..
public void BindMyQuantity()
{
for (int i = 1; i < 15; i++)
{
ddlMyQuantity.Items.Add(i.ToString());
}
}
Also i am not sure if i can do that, but the code is not complaining.. adding SelectedValue in the asp declaration
You can use OnRowDataBound to dynamically bind your dropdown:
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
var dropdownList = (DropDownList)e.Row.FindControl("ddlMyQuantity");
for (int i = 1; i < 15; i++)
{
dropdownList.Items.Add(i.ToString());
}
dropdownList.SelectedValue =
Convert.ToString(DataBinder.Eval(e.Row.DataItem, "Quantity"));
}
}
Add binding:
<asp:GridView ... OnRowDataBound="GridView_RowDataBound">
...
</asp:GridView>
As per my knowledge, the best option would be to write this code in "RowDataBound" event of the Grid. See sample code below.
protected void GridView_RowDataBound(..)
{
if (e.Row.RowType.Equals(DataControlRowType.DataRow))
{
DropDownList ddl = e.Row.FindControl("ddlMyQuantity") as DropDownList;
if (ddl != null)
{
for (int i = 1; i < 15; i++)
{
ddl.Items.Add(i.ToString());
}
}
}
}
In the aspx page, provide this
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlMyQuantity"></asp:DropDownList>
</ItemTemplate>
Hope this Helps!!
<asp:TemplateField HeaderText="Type Cargo" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="10%" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataValueField="DESCRIPTION"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
Code Behind will look like this...
Dim rowId As DropDownList
For i As Integer = 0 To gridView1.Rows.Count - 1
Dim gridrow As GridViewRow = gridView1.Rows(i)
rowId = DirectCast(gridrow.FindControl("DropDownList1"), DropDownList)
Dim dt As DataTable = Get_List()
rowId.DataSource = dt
rowId.DataBind()
Next
Get_List is a Function that returns a DataTable

Categories