1
votes

I just want to ask how I can update or change the cell value of column 'quantity' in my DataGridView when I select a certain row. I have 3 columns in my DataGridView which are Item Name, Quantity and Price. Every time I click the button 'add' or 'less' on my form, the quantity of the selected row item will either add to or subtract 1 from the quantity column and the price will also update every time the quantity increments or decrements. Here is my code when I add my item to my DataGridView.

I'm not really sure if I got it right to add items to my datagrid.

cmd = new MySqlCommand("SELECT * FROM tblmenu", dbConn);
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
    Button btn = new Button();
    btn.Text = rdr["menuName"].ToString();
    btn.Width = 126;
    btn.Height = 80;
    btn.Click += delegate
    {
        MySqlConnection cnn2 = new MySqlConnection(sqlConn.connString);
        cnn2.Open();
        cmd = new MySqlCommand("SELECT menuName, menuPrice FROM tblmenu WHERE menuName = @name", cnn2);
        cmd.Parameters.AddWithValue("@name", btn.Text);
        MySqlDataReader rdr2 = cmd.ExecuteReader();
        while (rdr2.Read())
        {
            dataGridView1.Rows.Add(rdr2.GetString("menuName").ToUpper(), 1, rdr2.GetDouble("menuPrice"));
        }
        dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
        lblQty.Text = dataGridView1.RowCount.ToString();
    };
}

I have tried this but when I click another set of item, the quantity from the previous selected item still increments.

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    Add.Click += delegate
    {
        dataGridView1.Rows[e.RowIndex].Cells["quantity"].Value = Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells["quantity"].Value) + 1;
    };
    Minus.Click += delegate
    {
        dataGridView1.Rows[e.RowIndex].Cells["quantity"].Value = Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells["quantity"].Value) - 1;
    };
}
2

2 Answers

1
votes

First of all, using dataGridView1_CellContentClick does not serve the purpose at all. You intend to increase or decrease quantity on Add or Minus button click. I would use dataGridView1.CurrentRow property to get hold of CurrentRow and manipulate quantity column.For updating price column, you should have a Rate column or a constant Rate value to multiply it with quantity. Do you have it? If not then I don't see how you arrive on price calculation. However assuming you have one :

void quantity_change(object sender, EventArgs e){
    var row=dataGridView1.CurrentRow;

    if(row==null || row.Index<0) 
    return;
    var unit = (sender==add)?1:-1;
    var quantity = Convert.ToInt32(row.Cells["quantity"].Value) + unit;

    row.Cells["quantity"].Value = quantity;
    //assuming you have rate column...
    var rate = Convert.ToDouble(row.Cells["Rate"].Value);
   row.Cells["Price"].Value = quantity * rate;
}

Now bind Click event of your Add & Minus Buttons to the method above in Form constructor.

public myForm(){
    InitializeComponents();
    Add.Click+=quantity_change;
    Minus.Click+=quantity_change;
}

You can also use form's Load event if you want.

2
votes

I suggest you consider binding your DataGridView to a data source. You should not perform data operations on the UI if you can avoid it.

To demonstrate this,

private void quantityChangeClick(object sender, EventArgs e)
{
    addToQuantity((Button)sender == this.Add ? 1 : -1);
    updateTotal();
}

private void addToQuantity(int howMuch)
{
    var selectedRowIndices = dataGridView1.SelectedRows.OfType<DataGridViewRow>().Select(ro => ro.Index);
    this.rows.Where((r, i) => selectedRowIndices.Contains(i)).ToList().ForEach(
        r => r.Quantity = Math.Max(0, r.Quantity + howMuch));

    this.dataGridView1.Refresh();
}

// calculate the total from the data source as well
private void updateTotal()
{
    var total = Math.Round(this.rows.Sum(r => r.Quantity * r.Price), 2, MidpointRounding.AwayFromZero);
    this.TotalLabel.Text = string.Format("₱{0:0.00}", total);
}

I have used some dummy data to demo this on my end, that is the Row class. Actually, you could do a similar thing, and add a Row to the data source rows with each record from your database.

private class Row
{
    public string ItemName { get; set; }
    public int Quantity { get; set; }
    public double Price { get; set; }
    public Row(string i, int q, double p)
    {
        this.ItemName = i;
        this.Quantity = q;
        this.Price = p;
    }
}

private List<Row> rows = new List<Row>();

private void Form1_Load(object sender, EventArgs e)
{
    // instead, here you will add your rows from SQL
    rows.AddRange(new Row[]
    {
        new Row("item1", 0, 500),
        new Row("item2", 0, 400),
        new Row("item3", 0, 850)
    });
    this.dataGridView1.DataSource = rows;
    dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    Add.Click += quantityChangeClick;
    Minus.Click += quantityChangeClick;
}

Example