I am currently getting data from database, then if i checked the checkbox more than 2 rows, it will sum up the total of SENDQTY and send the details from GridView3 to GridView4. Now how can i check if the STOCKCODE from the 2 rows is different, it will prompt error message?
protected void showGridView()
{
int match = 0;
int total = 0;
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[9] { new DataColumn("DODetailID"), new DataColumn("SALESORDERNO"), new DataColumn("STOCKCODE"), new DataColumn("SENDQTY"), new DataColumn("scanflag"), new DataColumn("REJECT"), new DataColumn("DispatchOrderID"), new DataColumn("DispatchDATE"), new DataColumn("DELORDERNO") });
foreach (GridViewRow row in GridView3.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox CheckBox1 = (row.Cells[0].FindControl("CheckBox1") as CheckBox);
//int qty = Convert.ToInt32(row.Cells[4].Text);
if (CheckBox1.Checked)
{
string DODetailID = (row.Cells[1].FindControl("DODetailID") as Label).Text;
string SALESORDERNO = (row.Cells[2].FindControl("SALESORDERNO") as Label).Text;
string STOCKCODE = (row.Cells[3].FindControl("STOCKCODE") as Label).Text;
int SENDQTY = Convert.ToInt32((row.Cells[4].FindControl("SENDQTY") as Label).Text);
CheckBox scanflag = (row.Cells[5].FindControl("scanflag") as CheckBox);
string REJECT = (row.Cells[6].FindControl("REJECT") as Label).Text;
string DispatchOrderID = (row.Cells[7].FindControl("DispatchOrderID") as Label).Text;
string DispatchDATE = (row.Cells[8].FindControl("DispatchDATE") as Label).Text;
string DELORDERNO = (row.Cells[9].FindControl("DELORDERNO") as Label).Text;
Session["STOCKCODE"] = STOCKCODE.ToString();
dt.Rows.Add(DODetailID, SALESORDERNO, STOCKCODE, SENDQTY, scanflag, REJECT, DispatchOrderID, DispatchDATE, DELORDERNO);
match++;
total = total + SENDQTY;
GridView4.DataSource = dt;
GridView4.DataBind();
}
}
}
}
protected void btnContinue_Click(object sender, EventArgs e)
{
showGridView();
mp3.Show(); // this is showing GridView4
}
you need to run two for each loops. Run the for/each loop on the data first time in which you count check boxes (and stock code). You can then in code decide to run/use your existing loop.
Collection MyCheckList = New Collection;
Boolean ListBad = false;
foreach (GridViewRow row in GridView3.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox CheckBox1 = (row.Cells[0].FindControl("CheckBox1") as CheckBox);
Label txtStock = (row.Cells[0].FindControl("STOCKCODE") as Label);
if CheckBox.Checked {
if MyCheckList.Contains(txtStock.Text) {
ListBad = true;
Exit for;
else
ListBad.Add(txtSTock)
}
etc. etc. etc
etc. etc.
In other words, run a test/loop over the data - put the stockcode into a collection if checked, and if such a stockcode already exists, then you know more then 1 checked of a given stock exists, and thus your flag ListBad = true when you finish that loop process.
You could also add the collection idea to your existing loop. And upon exit, you know if more then one stockcode was checked. So you probably don't need a separate first loop, but you do have to "build up" a list of checked + stockcodes if you checking for an already existing stock code. So build up a checked list in that collection and thus you know if a stockcode been used + checked in that list more then once.
Related
I am building a bookstore using GridViews and data from my database. There are checkboxes and each row has a quantity textbox. I am validating to make sure the at least one checkbox is checked and that the selected row has a quantity input before hitting submit. When the user hits submit, the data selected should be populated into another gridview.
The issue i am having is that when i select two different books and hit submit, the books populated on the gridview is just repeating only one book twice.
*Also the lblError text is still showing when i set the visibility to false when I submit.
Here's a snippet of the submit button call:
protected void btnSubmit_Click(object sender, EventArgs e)
{
double saleCount = 0;
Processor p = new Processor();
Book objBook = new Book();
foreach (GridViewRow row in gvBooks.Rows)
{
CheckBox chkbx = (CheckBox)row.Cells[0].FindControl("cbBook");
string title = row.Cells[1].Text;
string authors = row.Cells[2].Text;
string isbn = row.Cells[3].Text;
DropDownList gvType = (DropDownList)row.Cells[4].FindControl("ddBookType");
DropDownList gvMethod = (DropDownList)row.Cells[5].FindControl("ddMethod");
TextBox qty = (TextBox)row.Cells[6].FindControl("txtQty");
String strType = Convert.ToString(gvType.Text);
String strMethod = Convert.ToString(gvMethod.Text);
if (chkbx.Checked && !(string.IsNullOrEmpty(qty.Text)))
{
panelHeader.Visible = false;
panelStudentInfo.Visible = false;
panelCampus.Visible = false;
panelCatalog.Visible = false;
panelStudentInfo2.Visible = true;
panelCampus2.Visible = true;
panelCatalog2.Visible = true;
gvBooks.Visible = false;
gvOrder.Visible = true;
panelButtons.Visible = false;
txtStudentID2.Text = txtStudentID.Text;
txtStudentName2.Text = txtStudentName.Text;
txtStudentAddr2.Text = txtStudentAddr.Text;
txtPhoneNo2.Text = txtPhoneNo.Text;
ddCampus2.Text = ddCampuses.Text;
lblError.Visible = false;
int quantity = Convert.ToInt32(qty.Text);
objBook.Title = title;
objBook.Authors = authors;
objBook.ISBN = isbn;
objBook.BookType = strType;
objBook.Method = strMethod;
objBook.Quantity = quantity;
objBook.Price = p.Calculate(isbn, strType, strMethod);
objBook.TotalCost = objBook.Price * objBook.Quantity;
orderList.Add(objBook);
saleCount += objBook.Quantity;
orderTotal = objBook.TotalCost + orderTotal;
p.UpdateDB(isbn, quantity, strMethod, objBook.TotalCost);
}
else
{
lblError.Text = "* Please select a book & enter a quantity";
lblError.Visible = true;
}
gvOrder.DataSource = orderList;
gvOrder.DataBind();
gvOrder.Columns[0].FooterText = "Totals";
gvOrder.Columns[5].FooterText = saleCount.ToString();
gvOrder.Columns[6].FooterText = orderTotal.ToString("C2");
}
}
You need to change your code from this
Book objBook = new Book();
foreach (GridViewRow row in gvBooks.Rows)
{
....
to this
foreach (GridViewRow row in gvBooks.Rows)
{
Book objBook = new Book();
.....
The reason is simple. If you create the Book instance outside the loop and, inside the loop, you set its properties and add it to the list, at the second loop you will change the properties of the same instance to different values and add the reference a second time to the list. At the end of the loop your list will have many references to the SAME instance and this single instance will have its properties set to the last values read inside the loop.
If you declare and initialize the Book instance inside the loop you have, at every loop, a different instance of Book to add to the list and each instance will have its own property values.
Looking better at your code, I think that all the code after the if check should go outside the loop even the setting of the datasource.
Here a stripped down layout of the code to highlight the relevant points.
protected void btnSubmit_Click(object sender, EventArgs e)
{
double saleCount = 0;
Processor p = new Processor();
// Prepare a list of errors
List<string> errors = new List<strig>();
foreach (GridViewRow row in gvBooks.Rows)
{
Book objBook = new Book();
....
if (chkbx.Checked)
{
// Probably it is better to check here also the quantity value
// not just for text in the textbox (it could be anything)
if(Int32.TryParse(qty.Text, out int quantity) && quantity > 0)
{
// We have at least one checkbox checked with a quantity, so no error!
.....
}
else
{
// We don't have a quantity, add book title to error list....
errors.Add($"Book {title} has no quantity!");
}
}
}
// Handle the errors, if any
if(errors.Count > 0)
{
lblError.Text = string.Join("<br/>, errors);
lblError.Visible = true;
}
else
{
lblError.Visible = false;
gvOrder.DataSource = orderList;
gvOrder.DataBind();
gvOrder.Columns[0].FooterText = "Totals";
gvOrder.Columns[5].FooterText = saleCount.ToString();
gvOrder.Columns[6].FooterText = orderTotal.ToString("C2");
}
}
I have a parent and child gridview setup. on the OnRowDataBound event I need the value of a parent gridview cell. this is not the DataKeys of the parent Gridview. I have commented out some of the things I have tried, but not getting quite there. I think the last two lines are close, but I am not sure what the correct syntax should be.
gvCustomers is the parentGV.
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string requestId = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvOrders = e.Row.FindControl("gvOrders") as GridView;
gvOrders.DataSource = GetData(string.Format("select top 10 * from Orders where RequestID='{0}'", requestId));
gvOrders.DataBind(); // this is the childGV
string cell_1_Value = gvCustomers.Rows[e.Row.RowIndex].Cells[0].Text;
string cell_2_Value = gvCustomers.Rows[e.Row.RowIndex].Cells[1].Text;
}
}
This is now working using:
foreach (GridViewRow gr in gvCustomers.Rows)
{
string requestStatus = gvCustomers.Rows[gr.RowIndex].Cells[3].Text;
}
But is there anyway to get the same value using the name of the column?
You could try the following:
if (e.Row.RowType == DataControlRowType.DataRow)
{
string requestId = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvOrders = e.Row.FindControl("gvOrders") as GridView;
gvOrders.DataSource = GetData(string.Format("select top 10 * from Orders where RequestID='{0}'", requestId));
gvOrders.DataBind(); // this is the childGV
System.Data.DataRowView dr = (System.Data.DataRowView)e.Row.DataItem;
string requestStatus = dr["myColumnHeader"].ToString();
}
}
I try to develop a c# application(gathering products by their barcodes) to windows ce handheld device with compact framework 3.5
I have a datagrid and datagrid is bind with a datatable by sql. There are 4 columns in my datagrid, 3rd column represents the quantity of the products needs to be collected, and last column comes with the default value 0(quantity collected). Whenever user enters a product code, quantity of the product increases 1 by 1.
I want to make background color of the row blue when user enters corresponding product code(to show which product is being collected)
and also I want to make background color green if user collects the needed products.
I tried coloring row by selected index but it does not work. When selection gone , colours are gone.
Here is a picture of screen when needed quantity of product was collected.
Here is when I want to see the processed row.
Below is my code of the keypress event of the textbox(entering of product code)
private void txtUrunkod_KeyPress(object sender, KeyPressEventArgs e)
{
foreach (System.Data.DataColumn col in dt.Columns) col.ReadOnly = false;
if (e.KeyChar == (char)Keys.Enter)
{
islemkod = txtUrunkod.Text;
islemkod.Trim();
if (islemkod.Contains('/'))
{
serikodbol = islemkod.Split('/');
urunKodum = serikodbol[0];
DataRow row = dt.Select("urunkodu='" + urunKodum + "'").FirstOrDefault();
int guncelle = Convert.ToInt32(row[3]);
guncelle++;
row[3] = guncelle;
}
else if (islemkod.Length == 8)
{
SqlCommand cmd = new SqlCommand("exec MY_TOPUK_BILGI_GETIR '" + islemkod + "'", conStr);
conStr.Open();
SqlDataReader dr = cmd.ExecuteReader();
uk = new DataTable();
uk.Load(dr);
conStr.Close();
//toplamaGrid.Select(0);
foreach (DataRow row2 in uk.Rows)
{
urunKodum = row2[0].ToString();
}
DataRow row = dt.Select("urunkodu='" + urunKodum + "'").FirstOrDefault();
int guncelle = Convert.ToInt32(row[3]);
guncelle++;
row[3] = guncelle;
int index = -1;
bool found = false;
foreach (DataRow datr in dt.Rows)
{
index++;
string d = datr["urunkodu"].ToString();
if (datr[0].ToString() == urunKodum)
{
found = true;
break;
}
}
if (found && !row[2].Equals(row[3]))
{
toplamaGrid.Select(index);
toplamaGrid.SelectionBackColor = Color.Blue;
}
else if (row[2].Equals(row[3]))
{
toplamaGrid.Select(index);
toplamaGrid.SelectionBackColor = Color.Green;
//toplamaGrid.UnSelect(index);
}
}
else if (islemkod.Length == 7 && islemkod[0] == 'P')
{
}
else//islemkod.Length != 8 && !islemkod.Contains('/')
{//
urunKodum = txtUrunkod.Text;
txtUrunkod.Visible = false;
lblurunkod.Visible = false;
txtifAdres.Visible = true;
lbladressor.Visible = true;
txtifAdres.Focus();
}
updated = true;
txtUrunkod.Text = "";
sonindex = 0;
}
}
I couldnt find many info about this. Any help will be important. Thanks for any help!
First of all I experienced the same problem. Make use of DataGridFormatCellEventArgs for coloring the solution.
explained here Add the DataGrid file to your code in the link. (DataGridFormatCellEventArgs.cs and FormattableTextBoxColumn.cs) These files contain the Paint class that was used to do the coloring.
different example
I hope I could help. If you experience difficulties, I can give an example from my own code.
I have a paging GridView in my ASP.NET project in which I do insertions of human resources into a database. My GridView loads everytime all the human resources inserted into the data base.
Now everytime I add a new row (human resource) or modify an existing one, I want it to be highlighted in the grid to make clear to the user that the operation was executed. I haven´t found a good way yet and the fact that the gridview is paged makes it more complex. I would appreciate some help :)
I'm adding the rows by binding de grid with a dataTable:
protected void llenarGrid() //se encarga de llenar el grid cada carga de pantalla
{
DataTable recursosHumanos = crearTablaRH();
DataTable dt = controladoraRecursosHumanos.consultarRecursoHumano(1, 0); // en consultas tipo 1, no se necesita la cédula
Object[] datos = new Object[4];
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
datos[0] = dr[0];
datos[1] = dr[1];
datos[2] = dr[2];
int id = Convert.ToInt32(dr[3]);
String nomp = controladoraRecursosHumanos.solicitarNombreProyecto(id);
datos[3] = nomp;
recursosHumanos.Rows.Add(datos);
}
}
else
{
datos[0] = "-";
datos[1] = "-";
datos[2] = "-";
datos[3] = "-";
recursosHumanos.Rows.Add(datos);
}
RH.DataSource = recursosHumanos;
RH.DataBind();
}
protected DataTable crearTablaRH()
{
DataTable dt = new DataTable();
dt.Columns.Add("Cedula", typeof(int));
dt.Columns.Add("Nombre Completo", typeof(String));
dt.Columns.Add("Rol", typeof(String));
dt.Columns.Add("Nombre Proyecto");
//dt.
return dt;
}
Store the Primary Key / A unique value which uniquely identifies the row in View State when you are inserting the row :
Let's assume the first Column has unique value. Add below line at the end of your llenarGrid() method.
ViewState["LastRowUniqueValue"] = datos[0];
Handle the Page_PreRender event, highlight the inserted row:
protected void Page_PreRender(object sender, EventArgs e)
{
string lastInsertedRowValue = string.Empty;
// only highlight the row if last inserted values are NOT a Hyphen -
if (ViewState["LastRowUniqueValue"] != "-")
{
// Assuming the Unique value is String, else cast accordingly
string lastInsertedRowValue = (string)ViewState["LastRowUniqueValue"];
int rowCnt = 0;
foreach (GridViewRow row in GridView1.Rows)
{
string CellText = row.Cells[0].Text;
if (CellText.Equals(lastInsertedRowValue))
{
row.Attributes.Add(“bgcolor”, “Yellow”);
break;
}
rowCnt++;
}
}
}
I use the rowdatabound event to find the row that has been edited and then assign a bootstrap css class to that row like this:
e.Row.CssClass = "danger";
I am trying to implement a checkbox within gridview,
The job of this checkbox is to verify a record,
When this verify button is pressed, all items with a checked checkbox are inputted into the database
This is my code:
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox cbox = ((CheckBox)row.FindControl("Verify"));
if (cbox.Equals(true))
{
String DraftsText = ((TextBox)row.FindControl("numDrafts")).Text;
String TCtext = ((TextBox)row.FindControl("numTC")).Text;
if (row.RowType == DataControlRowType.DataRow)
{
//Header trs = new Header();
// GridView1.Rows[0].FindControl("numTC");
if (TCtext != "" && DraftsText != "")
{
// try
// {
string date = row.Cells[4].Text;
DateTime dateTime = Convert.ToDateTime(date);
string dateFormatted = dateTime.ToString("d-MMM-yy");
string unit = row.Cells[5].Text;
string currency = row.Cells[6].Text;
string totalFC = row.Cells[7].Text;
string totalDC = row.Cells[8].Text;
int d = Convert.ToInt32(DraftsText);
int tc = Convert.ToInt32(TCtext);
hdr = new Header(d, tc, dateFormatted, unit, currency, totalFC, totalDC);
hdr.InsertFCTC(hdr);
}
}
}
}
}
I might be going at this the wrong way but in the if (cbox.Equals(true))
its giving me an exception: Object reference not set to an instance of an object.
Any idea what i can do to solve this?
Many Thanks
This if (cbox.Equals(true)) should be if (cbox.Checked)
Since your cbox is a checkbox object it can't be used to compare, so you have to use the cbox Checked Property, which will return true/false
You receive a NullPointerException because the suggested checkbox wasn't found! Or the direct cast into an instance of type CheckBox doesn't worked as expected.
Change your code to something like this and retry:
CheckBox cbox = ((CheckBox)row.FindControl("Verify"));
if (cbox != null && cbox.Checked)
{
....
}