I'm writing a cart function for a webpage project I have. On the cart page, it checks your cart ID in a cookie, and then gets all of your items in the database. So, every item in the Cart table is dynamically created. On the .aspx page, there is an empty table created. In the codebehind, a new row and cells are created for each item.
I'm having trouble with updating the Quantity of a certain item. For each item in the cart, a textbox and button are dynamically created for the quantity, and updating the quantity. The quantity is set to whatever the quantity is in the database on page load. I can't seem to get the value of the textbox after it has been changed, for example from 1 to 2.
Here's a summary of how the table is populated. I've shortened it a lot, just to show how i'm loading the data into the table.
protected void Page_Load(object sender, EventArgs e){
cartpopulate(cartID);
}
private void cartpopulate(int cartID){
//for each item in database where cartID is paramater cartID
//create a row
//get the product name, image, price, quantity, options, and make a cell for each
//calculate total price from quantity and price
//add in delete and quantity update buttons
For ease, lets just assume all the quantites are 1. So, on page_load, it will set all of the quantities to 1. I think my problem is that the following code sets the value of the textbox to whatever the quantity is when it's populated, which would be 1. When you change it to 2 or whatever, the value is already set and the 2 does nothing. The database updating part works, I'm just having trouble getting the second value '2'.
Here's the quantity update code...
if (prod.Quantity == null) { quantitylabel.Value = 1.ToString(); }
else { quantitylabel.Value = prod.Quantity.ToString() ; }
quantityinput.ID = "quantity" + i.ToString();
quantityinput.Width = 20;
quantityinput.Text = quantitylabel.Value.ToString();
quantitycell.Controls.Add(quantityinput);
quantitycell.CssClass="cartitem";
row.Cells.Add(quantitycell);
Button btnUpdate = new Button();
btnUpdate.Text = "Update";
string arg = quantityinput.Text;
btnUpdate.CommandName = "update";
btnUpdate.CommandArgument = arg;
btnUpdate.Command += (s, e) =>
{
string quanupdate = Convert.ToString(e.CommandArgument);
int quanint = Convert.ToInt32(quanupdate);
prod.Quantity = quanint;
db.SubmitChanges();
Response.Redirect("cart.aspx");
};
I've looked at a few different solutions, but none of them seem to work. Two things I suspect are the issue would be doing something on !IsPostBack, or recreating the dynamically created controls on postback. I'm self-taught at web programming, so I'm not 100% sure how to do that, but I think one of those are the issue.
Thanks in advance
try to use static variables i.e use prod.Quantity as static variable
Related
I'm new-ish to C# and I'm trying to input a list of objects into a datagridview. I constantly add items to this list each time I click a button and the datagridview should refresh by setting it's data source back to the list.
Here is the list:
List<Models.OrderItem> orderitemlist = new List<Models.OrderItem>();
And here is the code that adds to the list and refreshes the list:
private void btnAddToOrder_Click(object sender, EventArgs e)
{
int quantity = Convert.ToInt32(tbAddOrderQuantity.Text);
int stock = Convert.ToInt32(ItemDataGrid.CurrentRow.Cells[6].Value);
int newstock = stock - quantity;
if (newstock < 0)
MessageBox.Show("You do not have enough items in stock for this.");
else
{
ItemDataGrid.CurrentRow.Cells[6].Value = newstock;
int itemID = Convert.ToInt32(ItemDataGrid.CurrentRow.Cells[0].Value);
string itemname = Convert.ToString(ItemDataGrid.CurrentRow.Cells[1].Value);
int sellprice = Convert.ToInt32(ItemDataGrid.CurrentRow.Cells[5].Value);
Models.OrderItem item = new Models.OrderItem(itemID, itemname, sellprice, quantity);
orderitemlist.Add(item);
RefreshItemsOnOrderData();
RefreshPrice();
}
}
private void RefreshItemsOnOrderData()
{
ItemOnOrderDataGrid.DataSource = orderitemlist;
}
The list will update with the first item however when I try to add another item it seems to run the block of code however doesn't actually add it to the datagrid view. Is anyone able to help? Have I made a simple error I just can't see?
As mentioned,
Set the source to null, re-ref the list, then reset bindings
ItemOnOrderDataGrid.DataSource = null;
ItemOnOrderDataGrid.DataSource = orderitemlist;
ItemOnOrderDataGrid.ResetBindings();
You may want to try omitting the null. I can't recall if this works without the null.
I am developing a .NET Windows Forms application. Frankly, I am absolute beginner to .NET windows forms. But I am ASP.NET developer. I am on my first windows forms project. Now I am having a problem with binding data to DataGridView using Entity Framework. I want to add two custom button columns. But I do not know how to do it since I am absolute beginner to Windows Forms controls.
My code is below:
RestaurantContext context = new RestaurantContext();
var dbFoods = context.Foods;
List<FoodMenuRow> rows = new List<FoodMenuRow>();
foreach(var food in dbFoods)
{
FoodMenuRow row = new FoodMenuRow
{
FoodId = food.Id,
FoodEnName = food.EnName,
FoodMmName = food.MmName,
IsAvailable = food.Available
};
rows.Add(row);
}
dataGridFoodMenu.DataSource = rows;
As you can see, I load data from database, then assign value to object, FoodMenuRow to bind data. Because I don't want to bind directly to Entity of EF.
This is the definition if class FoodMenuRow
public class FoodMenuRow
{
public int FoodId { get; set; }
public string FoodMmName { get; set; }
public string FoodEnName { get; set; }
public bool IsAvailable { get; set; }
}
When I run my code, I got something like this:
But I want to add two extra columns at the end. Both added columns will contain a button each. Then I set event for each button. Buttons something like "Edit" and "Delete". Their logic will be so complicated. I don't want to bind directly from database. I just want to bind with objects.
The posted code looks odd in the sense that it appears to be making a list of food items when it is not necessary. Following the code... is getting the data from RestaurantContex whatever that may be. The variable dbFoods is obviously a list or Data Table of these food items. It is difficult to say what type of structure is returned. Whatever it is the code loops through this list/table and creates a new FoodMenuRow object with the appropriate properties set. Then this FoodMenuRow is added to the rows list. This looks unnecessary since it appears you could possibly use dbFoods itself as a DataSource to dataGridFoodMenu. After the rows list is filled it is added as a DataSource to dataGridFoodMenu.
Since the two buttons you described “Edit” and “Delete” would not actually be part of the data in gataGridFoodMenu you can add these button columns after the grid is filled like below.
DataGridViewButtonColumn buttonColEdit = new DataGridViewButtonColumn();
buttonColEdit.Name = "Edit";
buttonColEdit.Text = "Edit";
buttonColEdit.UseColumnTextForButtonValue = true;
DataGridViewButtonColumn buttonColDelete = new DataGridViewButtonColumn();
buttonColDelete.Name = "Delete";
buttonColDelete.Text = "Delete";
buttonColDelete.UseColumnTextForButtonValue = true;
dataGridFoodMenu.Columns.Add(buttonColEdit);
dataGridFoodMenu.Columns.Add(buttonColDelete);
The added buttons should display like below.
Once the buttons have been added to the dataGridFoodMenu the only thing left is to capture when they have been clicked. The dataGridFoodMenu event CellContentClick is one event that will allow you to capture when these buttons have been clicked. Looking at the above picture the “Edit” column is in column 4 and the “Delete” column is in column 5. When the CellContentClick event is fired a check can be made to see if one of the button columns was clicked and perform the necessary “Edit” or “Delete”.
private void dataGridFoodMenu_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if (e.ColumnIndex == 4) {
MessageBox.Show("EDIT button clicked at row: " + e.RowIndex);
}
else {
if (e.ColumnIndex == 5) {
MessageBox.Show("DELETE button clicked at row: " + e.RowIndex);
}
else {
// buttons not clicked - ignoring
//MessageBox.Show("Button cells were not clicked -- row: " + e.RowIndex + " Column: " + e.ColumnIndex);
}
}
}
I am hoping this may help.
I have a dropdownlist that cannot be used for editing purpose. When button Edit is clicked inside listview where data exists, data is supposed to pass back to dropdownlist and other textboxes where the form is located outside listview. Passing data back to textboxes is ok. The problem is dropdownlist data that I want to edit was added to dropdownlist as another record. Please take a loot at picture, and I have to reselect the correct one. Otherwise, that selected data (e.g. December in picture) has no datavaluefield and it stops running if I didn't choose bottom December and click Update button. Here is my code for dropdownlist for months. Any help is appreciated for this. Thank you.
public void BindMonth()
{
ddlStartMonth.DataSource = objUIHelpers.GetAllMonths();
ddlStartMonth.DataTextField = "StartMonthName";
ddlStartMonth.DataValueField = "MonthId";
ddlStartMonth.DataBind();
ddlStartMonth.Items.Insert(0, "Select Start Month");}
Then, I put this method in page load like this.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindMonth();
}
}
This is listview data item editing
protected void lvEducation_ItemCommand(object sender, ListViewCommandEventArgs e)
{
switch (e.CommandName)
{
//Delete Method will be fired when command name "Delete" inside Listview is clicked.
case ("Delete"):
int EducationId = Convert.ToInt32(e.CommandArgument);//pass Id of Experience to identify datarow to delete
// DeleteEducationById(ExperienceId);//Call bind to delete method and pass ExperienceId as argument
break;
//Edit Method will fired when command name "Edit" inside Listview is clicked.
case ("Edit"):
EducationId = Convert.ToInt32(e.CommandArgument); //pass Id of Experience to identify datarow to edit
BindEducationDataToEdit(EducationId);//Call bind to edit method and pass ExperienceId as argument
break;
}}
This is part of method that triggers to pass back data to edit.
public void BindEducationDataToEdit(int EducationId)
{
Education edu = objJFUserBAL.GetEducationByIdToEdit(EducationId);
txtAdditionalInfo.Text = edu.AdditionalInfo.ToString();
ddlEndMonth.SelectedItem.Text = edu.mo.EndMonthName;
}
When selected data is posted back for editing, I have extra data like this.
You should not be updating the SelectedItem.Text. This is changing the displayed text. Instead you should be updating which item is selected.
If you do not have access to the value of the month name, you can do the following:
ddlEndMonth.Items.FindByText(edu.mo.EndMonthName).Selected = true;
which will select the item with the month text assuming one exists.
If it is possible to have an edu.mo.EndMonthName which does not exist in the list of items, you will want to do some checks for null and treat accordingly.
You have to fill a list manually, because auto binding is not going to let you put a "select your month" item unless you have one in your data base :
public void BindMonth()
{
List<Month> listOfMonth = new List<Month>();
Month fakeMonth = new Month();
// you need to see your own
//code and try to make a fake month with these parameters you want
fakeMonth.StartMonthName = "Select Start Month";
fakeMonth.MonthId = 0;
listOfmounth.Add(fakeMonth);
foreach(Month m in objUIHelpers.GetAllMonths())
{
listOfMonth.Add(m)
}
ddlStartMonth.DataSource = listOfMonth;
ddlStartMonth.DataTextField = "StartMonthName";
ddlStartMonth.DataValueField = "MonthId";
ddlStartMonth.DataBind();
ddlStartMonth.Items.Insert(0, "Select Start Month");}
}
I have a project to register customers using a DataGridView and It has 3 buttons:
"add" adds the values from the textbox
"delete" deletes the selected value in the DataGridView
"new" generates the next id number (they're consecutives) and clears all the textboxes fields
I think of adding a button named "cancel" to revert changes generated by the button "new" and it has to select the last edited row and show its cells values in the textbox.
I made a "cancel" button to select the last row in the list, but the last row in the list is not always the last edited
I'm using Windows Forms, not using a database.
private void bttn_cust_cancel_Click(object sender, EventArgs e)
{
if (dgv_customer.Rows.Count > 0)
{
dgv_customer.Rows[dgv_customer.Rows.Count - 2].Selected = true;
int i;
i = dgv_customer.SelectedCells[0].RowIndex;
txt_cust_clave.Text = dgv_customer.Rows[i].Cells[1].Value.ToString();
txt_cust_name.Text = dgv_customer.Rows[i].Cells[2].Value.ToString();
txt_cust_country.Text = dgv_customer.Rows[i].Cells[3].Value.ToString();
}
int currentType = Convert.ToInt32(txt_cust_id.Text);
txt_cust_id.Text = Convert.ToString(--currentType);
}
You could create a variable or class to hold the index and/or data of the last edited row. This class would be reinitialized every time the "New" button is pressed.
iv'e got an aspx page with some user controls , all of which contain a checkbox .
the checkbox is checked when the user control is added to the page.
the checkbox is set to auto post back
what i need is for when the auto post back occurs the user control will be gone.
first of all the way i load my user controls :
i load them as rows in a table and give their ID values the value of an entity that they represent
private void Load_Products(List<AppProduct> user_products)
{
HtmlTableRow row = null;
foreach(AppProduct p in user_products)
{
row = new HtmlTableRow();
tbl_products.Rows.Add(row);
CartProduct prd = (CartProduct)Page.LoadControl("~/UserControls/CartProduct.ascx");
prd.Title = p.Title;
prd.Price = p.Price.ToString();
prd.Pid = p.Pid.ToString();
prd.ID = p.Pid.ToString();
prd.State = 2;
prd.Product_Checked += new EventHandler(prd_Product_Checked);
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.Add(prd);
row.Cells.Add(cell);
}
}
the CartProduct UserControl represents the AppProduct Entity
now the way i removed the product (usercontrol) was by removing it from the list as follows :
void prd_Product_Checked(object sender, EventArgs e)
{ // this removes the product from the same list that the load products function gets
ProductChangedEventArgs args = (ProductChangedEventArgs)e;
cart.RemoveProduct(uid, args.Pid);
Response.Redirect("~/Pages/cart.aspx");
}
now this works , but it seems wrong to have to postback and then redirect again in order to take affect the removal from the list occur's on the post back , but takes affect
only on the next page load, when the list is re-loaded .
if i could some how remove the item from the list during the page load of the post back
with out having to re-direct again.
any ideas how i could skip the redirect ?
i thought of maybe sending arguments with the postback but i don't know if that's even possible , cause then i could send the product id and remove it from the list before Load_Products is called .
thanks in advance
eran.
Instead of the Redirect why don't you simply call Load_Products again with the updated list of products?