Show Total Row In Grid Each Time Name Changes - c#

I am attempting to display a grid on my page and each time the name in the grid changes display a Total for that name. However, I keep getting a error of Object not set to instance of an object This is my syntax I am trying, can someone take a look and fill me in on what I am doing wrong?
<asp:GridView ID="gvTest" runat="server" OnDataBound = "gvODB" OnRowCreated = "gvORC" >
<Columns>
<asp:BoundField DataField="" HeaderText="userID"></asp:BoundField>
<asp:BoundField DataField="employeename" HeaderText="Name"></asp:BoundField>
<asp:BoundField DataField="hoursworked" HeaderText="Daily Hours"></asp:BoundField>
</Columns>
</asp:GridView>
private int currentId = 0;
private decimal subTotal = 0;
private decimal total = 0;
private int subTotalRowIndex = 0;
protected void gvORC(object sender, GridViewRowEventArgs e)
{
DataTable dt = new DataTable();
subTotal = 0;
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
dt = (e.Row.DataItem as DataRowView).DataView.Table;
int userID = Convert.ToInt32(dt.Rows[e.Row.RowIndex]["userID"]);
total += Convert.ToDecimal(dt.Rows[e.Row.RowIndex]["hoursworked"]);
if (userID != currentId)
{
if (e.Row.RowIndex > 0)
{
for (int i = subTotalRowIndex; i < e.Row.RowIndex; i++)
{
subTotal += Convert.ToDecimal(gvTest.Rows[i].Cells[2].Text);
}
this.AddTotalRow("Total", subTotal.ToString("N2"));
subTotalRowIndex = e.Row.RowIndex;
}
currentId = userID;
}
}
}
catch (Exception exception)
{
throw exception;
}
}
protected void AddTotalRow(string labelText, string value)
{
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
row.BackColor = ColorTranslator.FromHtml("#F9F9F9");
row.Cells.AddRange(new TableCell[3] { new TableCell (), //Empty Cell
new TableCell { Text = labelText, HorizontalAlign = HorizontalAlign.Right},
new TableCell { Text = value, HorizontalAlign = HorizontalAlign.Right } });
gvTest.Controls[0].Controls.Add(row);
}
EDIT --
The grid will return a userid, username and hours worked. And I want a total to be displayed for each individual username returned. Something like so
userid name hours
1646 Red 16
1646 Red 8
Total 24
1812 Blue 6
1812 Blue 8
Total 14
Now a userid, name and hours will ALWAYS be returned, the only time a null value would be returned is when all results have been added to the grid.

The idea is to generate the html that will display your simple "report". There are any number of ways to do this. If the data is read only then using a Grid is less appropriate than just building a table or set of divs, etc. You can look into the Repeater or ListView but here I demonstrate a simple table element:
The aspx markup that has a simple asp:Table with runat server:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:Table runat="server" ID="usertbl" border="1">
</asp:Table>
</asp:Content>
The Code behind:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Contrived Data table just because I need some data to demonstrate.
//I assume you are or can acquire a DataTable with your current solution.
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("UserID", typeof(int)));
dt.Columns.Add(new DataColumn("UserName", typeof(string)));
dt.Columns.Add(new DataColumn("Hours", typeof(int)));
DataRow row = dt.NewRow();
row[0] = 1646;
row[1] = "Red";
row[2] = 16;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1646;
row[1] = "Red";
row[2] = 8;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1812;
row[1] = "Blue";
row[2] = 6;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1812;
row[1] = "Blue";
row[2] = 14;
dt.Rows.Add(row);
//Simplify accumualtor logic by grouping on Userid
var users = dt.AsEnumerable().GroupBy(u => u[0]);
//For each group (each user id)
foreach (var item in users)
{
//adds the user hours
int accumulator = 0;
//For each set or rows in group
foreach (var dr in item)
{
accumulator += int.Parse(dr[2].ToString());
//Create a table row
TableRow tr = new TableRow();
//Add the cells to the table row
TableCell userIdCell = new TableCell();
userIdCell.Text = item.Key.ToString();
tr.Cells.Add(userIdCell);
TableCell userNameCell = new TableCell();
userNameCell.Text = dr[1].ToString();
tr.Cells.Add(userNameCell);
TableCell hoursCell = new TableCell();
hoursCell.Text = dr[2].ToString();
tr.Cells.Add(hoursCell);
//Add the row to the table
usertbl.Rows.Add(tr);
}
//create summary row
TableRow totalRow = new TableRow();
//Skip a cells
totalRow.Cells.Add(new TableCell());
totalRow.Cells.Add(new TableCell());
//total cell
TableCell userTotalCell = new TableCell();
userTotalCell.Text = accumulator.ToString();
totalRow.Cells.Add(userTotalCell);
//Finally add the row
usertbl.Rows.Add(totalRow);
}
}
}
}
and finally the result:

Related

ASP C# Add Row to Table and Survive Postback

I'm looking for a simple way to create a running table of data input by a user in a submit form. The table really just needs to add a row with data that was just input, but more importantly, survive postback.
The table should have a header, then a row per 'set' of data entered the last submit.
For example:
<asp:Table ID="lastRecordTable" runat="server" ViewStateMode="Enabled"
AutoPostBack="true">
<asp:TableHeaderRow>
<asp:TableCell>A</asp:TableCell>
<asp:TableCell>B</asp:TableCell>
<asp:TableCell>C</asp:TableCell>
<asp:TableCell>D</asp:TableCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell>1</asp:TableCell>
<asp:TableCell>2</asp:TableCell>
<asp:TableCell>3</asp:TableCell>
<asp:TableCell>4</asp:TableCell>
</asp:TableRow>
</asp:Table>
Code Behind:
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
TableCell cell2 = new TableCell();
TableCell cell3 = new TableCell();
TableCell cell4 = new TableCell();
cell1.Text = 1.ToString();
cell1.Text = 2.ToString();
cell1.Text = 3.ToString();
cell1.Text = 4.ToString();
row.Cells.Add(cell1);
row.Cells.Add(cell2);
row.Cells.Add(cell3);
row.Cells.Add(cell4);
lastRecordTable.Rows.Add(row);
Any advice is appreciated.
Because you add the rows dynamically, you need to (re)create them on every page load, and that includes a PostBack. So move the adding of the row outside the IsPostBack check.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//not here
}
//but here
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
TableCell cell2 = new TableCell();
TableCell cell3 = new TableCell();
TableCell cell4 = new TableCell();
cell1.Text = 1.ToString();
cell1.Text = 2.ToString();
cell1.Text = 3.ToString();
cell1.Text = 4.ToString();
row.Cells.Add(cell1);
row.Cells.Add(cell2);
row.Cells.Add(cell3);
row.Cells.Add(cell4);
lastRecordTable.Rows.Add(row);
}
You don't need ViewStateMode="Enabled" and AutoPostBack="true" for this to work.
This is what I got to work:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
}
lastRecordTable();
}
Table Method:
public void lastRecordTable()
{
if (Session["lastRecord"] == null)
{
DataTable dt = new DataTable();
dt.Columns.Add("1");
dt.Columns.Add("2");
dt.Columns.Add("3");
dt.Columns.Add("4");
Session["lastRecord"] = dt;
GridView1.DataSource = dt;
GridView1.DataBind();
}
else
{
DataTable dt = (DataTable)Session["lastRecord"];
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
Modify Table:
protected void buttonSubmit_Click(object sender, EventArgs e)
{
//do stuff here
DataTable dt = Session["lastRecord"] as DataTable;
DataRow row = dt.NewRow();
row["1"] = "A";
row["2"] = "B";
row["3"] = "C";
row["4"] = "D";
dt.Rows.Add(row);
Session["lastRecord"] = dt;
lastRecordTable();
}
ASP:
<asp:GridView ID="GridView1" runat="server" ViewStateMode="Enabled"
AutoPostBack="true"></asp:GridView>
I'm very new to asp c#, so not 100% sure this is 'correct', but it works!

I am creating billing form. In that i added textbox and dropdownlist in gridview. now in textbox1 i want to fetch price from database.

I am creating billing form. In that i added textbox and dropdownlist in gridview. now in textbox1 i want to fetch price from database. so how do i get price in text box1? i tried a lot but i could not find the solution.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false"
OnRowCreated="Gridview1_RowCreated"
>
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Medicine Id" />
<asp:TemplateField HeaderText="Medicine Name">
<ItemTemplate>
<asp:DropDownList ID="DropDownList3" runat="server" AppendDataBoundItems="true">
<asp:ListItem Value="-1">Select</asp:ListItem>
<asp:ListItem>crocin</asp:ListItem>
<asp:ListItem>colgate</asp:ListItem>
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:DropDownList ID="DropDownList4" runat="server" AppendDataBoundItems="true">
<asp:ListItem Value="-1">Select</asp:ListItem>
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server"
Text="Add New Row"
onclick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"
onclick="LinkButton1_Click">Remove</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
</div>
<p>
</p>
<asp:TextBox ID="lblMessage" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="BtnSave" />
</form>
</body>
</html>
in cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Data;
using System.Collections.Specialized;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;
namespace WebApplication11
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
SetInitialRow();
}
}
// private ArrayList GetDummyData()
//{
// ArrayList arr = new ArrayList();
//arr.Add(new ListItem("Item1", "1"));
//arr.Add(new ListItem("Item2", "2"));
//arr.Add(new ListItem("Item3", "3"));
//arr.Add(new ListItem("Item4", "4"));
// arr.Add(new ListItem("Item5", "5"));
//return arr;
// }
// private void FillDropDownList(DropDownList ddl)
//{
// ArrayList arr = GetDummyData();
// foreach (ListItem item in arr)
// {
// ddl.Items.Add(item);
// }
// }
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));//for DropDownList selected item
dt.Columns.Add(new DataColumn("Column2", typeof(string)));//for DropDownList selected item
dt.Columns.Add(new DataColumn("Column3", typeof(string)));//for TextBox value
dt.Columns.Add(new DataColumn("Column4", typeof(string)));//for TextBox value
dr = dt.NewRow();
dr["RowNumber"] = 1;
// dr["Column3"] = 555;
dr["Column3"] = string.Empty;
dr["Column4"] = string.Empty;
dt.Rows.Add(dr);
//Store the DataTable in ViewState for future reference
ViewState["CurrentTable"] = dt;
//Bind the Gridview
Gridview1.DataSource = dt;
Gridview1.DataBind();
//After binding the gridview, we can then extract and fill the DropDownList with Data
DropDownList ddl1 = (DropDownList)Gridview1.Rows[0].Cells[1].FindControl("DropDownList3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[0].Cells[2].FindControl("DropDownList4");
// FillDropDownList(ddl1);
// FillDropDownList(ddl2);
}
private void AddNewRowToGrid()
{
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = dtCurrentTable.Rows.Count + 1;
//add new row to DataTable
dtCurrentTable.Rows.Add(drCurrentRow);
//Store the current data to ViewState for future reference
ViewState["CurrentTable"] = dtCurrentTable;
for (int i = 0; i < dtCurrentTable.Rows.Count - 1; i++)
{
//extract the DropDownList Selected Items
DropDownList ddl1 = (DropDownList)Gridview1.Rows[i].Cells[1].FindControl("DropDownList3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[i].Cells[2].FindControl("DropDownList4");
// Update the DataRow with the DDL Selected Items
dtCurrentTable.Rows[i]["Column1"] = ddl1.SelectedItem.Text;
dtCurrentTable.Rows[i]["Column2"] = ddl2.SelectedItem.Text;
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[i].Cells[3].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[i].Cells[4].FindControl("TextBox2");
dtCurrentTable.Rows[i]["Column3"] = box1.Text;
dtCurrentTable.Rows[i]["Column4"] = box2.Text;
}
//Rebind the Grid with the current data to reflect changes
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
private void SetPreviousData()
{
SqlConnection cnn = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=medical_store_management2;Integrated Security=True");
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
//TextBox box1 = (TextBox)Gridview1.Rows[i].Cells[1].FindControl("TextBox1");
// TextBox box2 = (TextBox)Gridview1.Rows[i].Cells[2].FindControl("TextBox2");
// DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[3].FindControl("DropDownList1");
// DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[4].FindControl("DropDownList2");
DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[1].FindControl("DropDownList3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[2].FindControl("DropDownList4");
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[4].FindControl("TextBox2");
//Fill the DropDownList with Data
// FillDropDownList(ddl1);
// FillDropDownList(ddl2);
if (i < dt.Rows.Count - 1)
{
String sql = ("select price from medicine where med_name='" + ddl1.Text + "'");
cnn.Open();
SqlCommand cmd = new SqlCommand(sql, cnn);
SqlDataReader dr;
dr = cmd.ExecuteReader();
//Set the Previous Selected Items on Each DropDownList on Postbacks
ddl1.ClearSelection();
ddl1.Items.FindByText(dt.Rows[i]["Column1"].ToString()).Selected = true;
ddl2.ClearSelection();
ddl2.Items.FindByText(dt.Rows[i]["Column2"].ToString()).Selected = true;
//Assign the value from DataTable to the TextBox
if (dr.Read())
{
box1.Text = dr.GetValue(0).ToString();
}
cnn.Close();
//box1.Text = dt.Rows[i]["Column3"].ToString();
box2.Text = dt.Rows[i]["Column4"].ToString();
}
rowIndex++;
}
}
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
AddNewRowToGrid();
}
protected void Gridview1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
LinkButton lb = (LinkButton)e.Row.FindControl("LinkButton1");
if (lb != null)
{
if (dt.Rows.Count > 1)
{
if (e.Row.RowIndex == dt.Rows.Count - 1)
{
lb.Visible = false;
}
}
else
{
lb.Visible = false;
}
}
}
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
LinkButton lb = (LinkButton)sender;
GridViewRow gvRow = (GridViewRow)lb.NamingContainer;
int rowID = gvRow.RowIndex;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 1)
{
if (gvRow.RowIndex < dt.Rows.Count - 1)
{
//Remove the Selected Row data and reset row number
dt.Rows.Remove(dt.Rows[rowID]);
ResetRowID(dt);
}
}
//Store the current data in ViewState for future reference
ViewState["CurrentTable"] = dt;
//Re bind the GridView for the updated data
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
//Set Previous Data on Postbacks
SetPreviousData();
}
private void ResetRowID(DataTable dt)
{
int rowNumber = 1;
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
row[0] = rowNumber;
rowNumber++;
}
}
}
private void InsertRecords(StringCollection sc)
{
StringBuilder sb = new StringBuilder(string.Empty);
string[] splitItems = null;
const string sqlStatement = "INSERT INTO medsale1 (mname,qty,price,total) VALUES";
foreach (string item in sc)
{
if (item.Contains(","))
{
splitItems = item.Split(",".ToCharArray());
sb.AppendFormat("{0}('{1}','{2}','{3}','{4}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3]);
}
}
using (SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=medical_store_management2;Integrated Security=True"))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand(sb.ToString(), connection))
{
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
lblMessage.Text = "Records successfully saved!";
}
protected void BtnSave_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection sc = new StringCollection();
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[1].FindControl("DropDownList3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[2].FindControl("DropDownList4");
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[4].FindControl("TextBox2");
//get the values from TextBox and DropDownList
//then add it to the collections with a comma "," as the delimited values
sc.Add(string.Format("{0},{1},{2},{3}", ddl1.SelectedItem.Text, ddl2.SelectedItem.Text, box1.Text, box2.Text));
// sc.Add(string.Format("{0},{1},{2},{3}", box1.Text, box2.Text, ddl1.SelectedItem.Text, ddl2.SelectedItem.Text));
rowIndex++;
}
//Call the method for executing inserts
InsertRecords(sc);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection sc = new StringCollection();
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[1].FindControl("DropDownList3");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[2].FindControl("DropDownList4");
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[4].FindControl("TextBox2");
// DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[3].FindControl("DropDownList1");
// DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[4].FindControl("DropDownList2");
//get the values from TextBox and DropDownList
//then add it to the collections with a comma "," as the delimited values
sc.Add(string.Format("{0},{1},{2},{3}", ddl1.SelectedItem.Text, ddl2.SelectedItem.Text, box1.Text, box2.Text));
rowIndex++;
}
//Call the method for executing inserts
InsertRecords(sc);
}
}
}
}
}
You can achieve this by detecting when user choose the medicine name or the quantity. In order to do this just add OnSelectedIndexChanged for your both DropDownLists :
OnSelectedIndexChanged="DropDownList3_SelectedIndexChanged"
OnSelectedIndexChanged="DropDownList4_SelectedIndexChanged"
This event will fire every time you change the selection of the item. You also need to set the AutoPostBack property for both DropDownLists to true, otherwise the events won't fire.
Now your code behind can look like this:
protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList medicineName = (DropDownList)sender;
if (medicineName.SelectedValue != "-1") // if medicine name is selected
{
GridViewRow row = (GridViewRow)medicineName.Parent.Parent; // find row
int quantity = Convert.ToInt32(((DropDownList)row.FindControl("DropDownList4")).SelectedValue); // find Quantity
if (quantity != -1) // if quanity is selected
{
int price = 1; // TODO: here you take the prize from the database by medicine name
price = price * quantity;
TextBox txtPrice = (TextBox)row.FindControl("TextBox1"); // find price textbox for this row
txtPrice.Text = Convert.ToString(price); // assign price value to this textbox
}
}
}
Everytime when user select item in medicine name dropdownlist, method checks if quantity is selected, and if yes you take the price from db, multiply by quantity and assign this value to the textbox. Of course in above example I didn't implement the part when you should take the price from db. Same way you have to implement the event for quanity dropdownlist.

How to insert values row by row in a gridview using temporary table(Data Table)

I have two gridviews in my asp.net page. Where the datas are coming from two different databases. In that, one gridview has select row function. Now what I want to do is, I need to generate my 3rd gridview row by row according to the selection of the 1st gridview's 2 cells and the 2nd gridview 1st column data.(1st column data is common for all the rows).
The values in the gridview is showing as expected, But it will only hold one row data at a time. When I go ahead to select another value from the dropdownlist the gridview refreshes and the existing data will disappear and the new data appears.
How can I have the selected datas inserted row by row in a gridview?
Here are my code given below:
protected void btnAssign_Click(object sender, EventArgs e)
{
SetInitialRowToGrid();
int rowIndex = 0;
if (ViewState["TempTable"] != null)
{
// Get TempTable from viewstate
var tempTable = (DataTable)ViewState["TempTable"];
DataRow tempRow = null;
if (tempTable.Rows.Count > 0)
{
for (int i = 1; i <= tempTable.Rows.Count; i++)
{
// Get Grid's Label values
var EmpID =
(Label)grdEmp.SelectedRow.FindControl("lblEmpID");
var firstName =
(Label)grdEmp.SelectedRow.FindControl("lblFirstName");
var date = DateTime.Now.ToString();
var planID =
(Label)grdPlanID.Rows[rowIndex].Cells[1].FindControl("lblPlanID");
// Create new row and update Row Number
tempRow = tempTable.NewRow();
tempTable.Rows[0]["Emp_ID"] = EmpID.Text;
tempTable.Rows[i - 1]["First_Name"] = firstName.Text;
tempTable.Rows[i - 1]["Created_Time"] = date;
tempTable.Rows[i - 1]["Plan_ID"] = planID.Text;
rowIndex++;
}
// Add data to datatable and viewstate
tempTable.Rows.Add(tempRow);
ViewState["TempTable"] = tempTable;
// Attach Gridview Datasource to datatable
grdList.DataSource = tempTable;
grdList.DataBind();
}
}
//Set Previous Data on Postbacks
SetPreviousData();
}
SetInitialRowToGrid() code is given below:
private void SetInitialRowToGrid()
{
// Initialize and Set initial row of Datatable
var tempDataTable = new DataTable();
tempDataTable.Columns.Add("Emp_ID");
tempDataTable.Columns.Add("First_Name");
tempDataTable.Columns.Add("Created_Time");
tempDataTable.Columns.Add("Plan_ID");
tempDataTable.Rows.Add("1", "", "", "");
// Store that datatable into viewstate
ViewState["TempTable"] = tempDataTable;
// Attach Gridview Datasource to datatable
grdList.DataSource = tempDataTable;
grdList.DataBind();
}
SetPreviousData() code is given below:
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["TempTable"] != null)
{
var tempTable = (DataTable)ViewState["TempTable"];
if (tempTable.Rows.Count > 0)
{
for (int i = 0; i < tempTable.Rows.Count; i++)
{
var EmpID =
(Label)grdEmp.SelectedRow.FindControl("lblEmpID");
var firstName =
(Label)grdEmp.SelectedRow.FindControl("lblFirstName");
var date = DateTime.Now.ToString();
var planID =
(Label)grdList.Rows[rowIndex].Cells[1].FindControl("lblPlanID");
EmpID.Text = tempTable.Rows[i]["Emp_ID"].ToString();
firstName.Text = tempTable.Rows[i]["First_Name"].ToString();
date = tempTable.Rows[i]["Created_Time"].ToString();
planID.Text = tempTable.Rows[i]["Plan_ID"].ToString();
rowIndex++;
}
}
}
}

Gridview - Loop through multiple header rows

In a console app, a gridview is created dynamically.
GridView gv = new GridView();
gv.AutoGenerateColumns = false;
for (int i = 0; i < dt.Columns.Count; i++)
{
BoundField boundfield = new BoundField();
boundfield.DataField = dt.Columns[i].ColumnName.ToString();
boundfield.HeaderText = arr[i].ToString();// dt.Columns[i].ColumnName.ToString();
gv.Columns.Add(boundfield);
}
Then, two more header rows are added. Here is a partial of one row:
GridViewRow HeaderGridRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell = new TableCell();
HeaderCell.Text = "";
HeaderCell.ColumnSpan = 4;
HeaderGridRow.Cells.Add(HeaderCell);
//more header cells added then another row here
gv.DataSource = dt;
gv.DataBind();
gv.Controls[0].Controls.AddAt(0, HeaderGridRow);
Using a foreach loop, adjusting separate cell borders not in the header is done:
foreach (GridViewRow row in gv.Rows)
{
TableCell tCell = row.Cells[0];
tCell.Attributes["style"] = "border-right:0";
}
I have been trying to find a way to loop through the header rows and adjust some borders on the cells.
Tried using foreach (GridViewRow row in gv.HeaderRow) but gv.HeaderRow does not have a public definition for GetEnumerator.
Tried for(int i = 0; i < gv.HeaderRow.Cells.Count; i++) but that doesn't seem to work either.
Anyone have any suggestions?
Thanks!!
Try this
GridViewRow headerRow = gv.HeaderRow;
TableCell hCell = headerRow.Cells[0];
hCell.Attributes["style"] = "border-right:0";
Hope it helps

databind a gridview populated in the code behind

I have tried a lot and have reached a dead end.
I have a to show multiple gridviews on one page and all these are getting populated dynamically.
i have figured a way to populate the gridview dynamically and display them, but i cannot get how to modify these values and display them as i want.
here is the code. for .aspx page
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">
<asp:Panel ID="Panel1" runat="server" ScrollBars ="Auto" Height="500px" BorderColor="#003399" BorderWidth="3px">
</asp:Panel>
</asp:Content>
and here is the code for .aspx.cs
for (int j = 0; j < 5; j++)
{
GridView Grid = new GridView();
ArrayList machID = new ArrayList();
ArrayList machName = new ArrayList();
Grid.ID = machGrps[j].ToString();
Grid.AllowSorting = true;
Grid.CellSpacing = 2;
Grid.GridLines = GridLines.None;
Grid.Width = Unit.Percentage(100);
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection(Session["ConnectionStringSQL"].ToString());
connection.Open();
SqlCommand sqlCmd = new SqlCommand("select MachineID, MachineName from Machines", connection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
sqlDa.Fill(dt);
connection.Close();
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
machID.Add(dt.Rows[i]["MachineID"].ToString());
machName.Add(dt.Rows[i]["MachineName"].ToString());
}
DataTable taskTable = new DataTable();
taskTable.Columns.Add("MachineID");
taskTable.Columns.Add("MachineName");
if (machID.Count != 0)
{
for (int i = 0; i < machID.Count; i++)
{
DataRow tableRow = taskTable.NewRow();
tableRow["MachineID"] = machID[i];
tableRow["MachineName"] = machName[i];
taskTable.Rows.Add(tableRow);
}
}
Session["TaskTable"] = taskTable;
Grid.DataSource = Session["TaskTable"];
Grid.DataBind();
Label label = new Label();
label.Text = "Machine Grp" + Grid.ID;
Panel1.Controls.Add(label);
Panel1.Controls.Add(Grid);
}
}
NOTE THIS CODE BELOW CANNOT BE DONE ANYMORE AS I POPULATE THE GRIDVIEW DIRECTLY FROM THE TABLES:
I used to modify like this when the ondatabound="GridView1_DataBound" if is called from the .aspx page
the databound code looks like this:
protected void GridView1_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow myRow in GridView1.Rows)
{
//this is where ID is stored in an label template
Label Label3 = (Label)myRow.FindControl("Label3");
int val = Convert.ToInt32(Label3.Text);
Image Image5 = (Image)myRow.FindControl("Image5");
if (Convert.ToInt32(Label3.Text) < 0)
{
Image5.ImageUrl = "~/NewFolder1/warning_16x16.gif";
}
else
{
Image5.ImageUrl = "~/NewFolder1/1258341827_tick.png";
}
}
}
Two things:
protected void GridView1_DataBound(object sender, EventArgs e) {
foreach (GridViewRow myRow in GridView1.Rows) {
// blah blah blah code goes here
}
}
should be
//now e is a
protected void Grid_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
// blah blah blah, this lets you work on one row at a time.
// since the framework does this per row, you don't need to parse the gridview
// yourself, altho you're more than welcome to.
// But you can get more control this way. I promise.
Label Label3 = (Label)e.Row.FindControl("Label3");
int val = Convert.ToInt32(Label3.Text);
Image Image5 = (Image)e.Row.FindControl("Image5");
if (val < 0)
{
Image5.ImageUrl = "~/NewFolder1/warning_16x16.gif";
}
else
{
Image5.ImageUrl = "~/NewFolder1/1258341827_tick.png";
}
// alternately write the code above like this:
Image Image5 = (Image)e.Row.FindControl("Image5");
Image5.ImageUrl = (val < 0) ? "~/NewFolder1/warning_16x16.gif" : "~/NewFolder1/1258341827_tick.png";
// that's called the ternary operator. Takes up less space, does the same thing.
}
}
Please don't ignore this part
Now to the other part, are you aware that you can still bind in the backside like thus:
GridView1.RowDataBound += GridView1_RowDataBound;
Put it here:
for (int j = 0; j < 5; j++)
{
GridView Grid = new GridView();
ArrayList machID = new ArrayList();
ArrayList machName = new ArrayList();
//NEW LINE (doesn't need the comment or the blank space tho)
Grid.RowDataBound += Grid_RowDataBound;
Grid.ID = machGrps[j].ToString();
Grid.AllowSorting = true;
Grid.CellSpacing = 2;
Grid.GridLines = GridLines.None;
Grid.Width = Unit.Percentage(100);
Do your dynamic edits on GridView1_RowDataBound not on GridView1_DataBound
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label Label3 = (Label)e.Row.FindControl("Label3");
....
}
}
Is it blowing up when you're binding the DataSource to the Session object?
Grid.DataSource = taskTable;

Categories

Resources