Update the quantity in datagridview C# - c#

I am currently developing a P.O.S software and i started to code the pay form. But i want when the user enters the same product to increment the quantity value and not to display it on another row, i coded it but it displays the updated row and the products on the other rows
public void dodadi() {
MySqlConnection connection = Connection.prevzemiKonekcija();
connection.Open();
try
{
if (string.IsNullOrWhiteSpace(txtBarajKod.Text))
{
return;
}
bool Found = false;
if (dataGridView1.Rows.Count > 0)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (Convert.ToString(row.Cells[0].Value) == txtBarajKod.Text)
{
row.Cells[3].Value = Convert.ToString(1 + Convert.ToInt64(row.Cells[3].Value));
Found = true;
}
}
}
if(!Found)
{
MySqlCommand command;
MySqlDataAdapter adapter;
DataTable tabela;
MySqlDataReader reader;
string query = "SELECT * FROM artikli WHERE barcode like '%" + txtBarajKod.Text + "%'";
command = new MySqlCommand(query, connection);
adapter = new MySqlDataAdapter(command);
tabela = new DataTable();
reader = command.ExecuteReader();
//dataGridView1.DataSource = tabela;
//adapter.Fill(tabela);
if (string.IsNullOrWhiteSpace(txtBarajKod.Text))
{
return;
}
if (reader.Read())
{
txtBarajKod.Text = reader.GetString("barcode");
txtNaziv.Text = reader.GetString("ProductName");
txtCena.Text = reader.GetString("SellPrice");
kolicina = 1;
txtKolicina.Text = kolicina.ToString();
}
else
{
txtBarajKod.Text = "";
txtNaziv.Text = "";
txtCena.Text = "";
txtKolicina.Text = "";
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
connection.Close();
}
}
private void dodadivotabela() {
cena = float.Parse(txtCena.Text);
kolicina = float.Parse(txtKolicina.Text);
konecnacena = cena * kolicina;
string prvred = txtBarajKod.Text;
string vtorred = txtNaziv.Text;
float tretred = cena;
float cetvrtred = kolicina;
float pettired = konecnacena;
dataGridView1.Rows.Add(prvred, vtorred, tretred, cetvrtred, pettired);
}
this is the second method that adds the data to the dgv

If I understood clearly, you don't want the value to show on the 4th cell of the 2nd and 3rd rows when you increment the value of the first row.
If I'm right, you should add a break statement in your foreach loop like so:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (Convert.ToString(row.Cells[0].Value) == txtBarajKod.Text)
{
row.Cells[3].Value = Convert.ToString(1 + Convert.ToInt64(row.Cells[3].Value));
Found = true;
break;
}
}
The break statement will allow you to exit your foreach loop once your condition is met for the first time. If you omit it it will loop over all the other rows and change the value in the 4th cell like in your screenshot because your condition is still met in the other rows.
UPDATED
Ok so you just need to clear your dataGridView1 before you add your updated row to it. I presume your dodadivotabela() method is called when you update the row with the incremented value. Add dataGridView1.Rows.Clear() to your method :
private void dodadivotabela()
{
cena = float.Parse(txtCena.Text);
kolicina = float.Parse(txtKolicina.Text);
konecnacena = cena * kolicina;
string prvred = txtBarajKod.Text;
string vtorred = txtNaziv.Text;
float tretred = cena;
float cetvrtred = kolicina;
float pettired = konecnacena;
dataGridView1.Rows.Clear();
dataGridView1.Rows.Add(prvred, vtorred, tretred, cetvrtred, pettired);
}

Related

Problem when i open second form from datagridview button in C#

I have two forms. First is the dashboard form (Form 1) which contains a datagridview with a button column for each row which opens a second form (Form 2) with the order details of the selected datagridview row. Everything works fine when it shows all records from the database, the button opens the Form 2 with all the details, id and everything. When i filter the datagridview by client or date or something else, i get the desired rows (clients, date etc), but if i click again on the edit button, i get the following error:
System.FormatException: 'Input string was not in a correct format.'
It is like the filtering changes something in the code or query but i can't figure out what, basicaly it is the same row, same data, but filtered.
Code of Form 1:
private void GridComenzi_CellClick(object sender, DataGridViewCellEventArgs e)
{
String colname = GridComenzi.Columns[GridComenzi.CurrentCell.ColumnIndex].Name;
DataGridViewRow row = this.GridComenzi.Rows[e.RowIndex];
if (colname == "Edit")
{
string editOrder = row.Cells[0].Value.ToString();
Editare ed = new Editare(editOrder);
ed.Show();
}
else
{
return;
}
}
Code of Form 2:
public Editare(string editOrder)
{
InitializeComponent();
EditOrderList.View = View.Details;
EditOrderList.FullRowSelect = true;
DataTable dt = GetOrderDetails(editOrder);
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
EditOrderList.Items.Add(dr["Denumire"].ToString());
EditOrderList.Items[EditOrderList.Items.Count - 1].SubItems.Add(dr["Cantitate"].ToString());
EditOrderList.Items[EditOrderList.Items.Count - 1].SubItems.Add(dr["Dimensiuni"].ToString());
EditOrderList.Items[EditOrderList.Items.Count - 1].SubItems.Add(dr["Comentarii"].ToString());
EditOrderList.Items[EditOrderList.Items.Count - 1].SubItems.Add(dr["NumeMaterial"].ToString());
EditOrderList.Items[EditOrderList.Items.Count - 1].SubItems.Add(dr["NumeFinisaj"].ToString());
if (dr["Livstatus"].ToString() == "Livrata")
{
radioLiv.Checked = true;
}
else
{
radioNeliv.Checked = true;
}
using (SqlDataAdapter sdatime = new SqlDataAdapter("SELECT OrderID, Clienti.NumeClient, Produse.Denumire, Produse.Cantitate, Produse.Dimensiuni, Produse.Comentarii, Produse.NumeMaterial, Produse.NumeFinisaj, IDComenzi.DataInitial,Comenzi.DataFinalizare, Comenzi.Factstatus, Comenzi.Livstatus FROM Comenzi INNER JOIN Clienti ON Comenzi.ClientID = Clienti.IDClient INNER JOIN Produse ON Comenzi.ProductID = Produse.IDProdus INNER JOIN IDComenzi ON Comenzi.OrderID = IDComenzi.IDComanda WHERE OrderID=#OrderID", con))
{
sdatime.SelectCommand.Parameters.Add("#OrderID", SqlDbType.Int).Value = editOrder; // ALSO POSSIBLE ERROR HERE (i didn't get this far)
DataTable dtTime = new DataTable();
sdatime.Fill(dtTime);
dateTimePicker1.Value = Convert.ToDateTime(dtTime.Rows[0]["DataInitial"].ToString());
dateTimePicker2.Value = Convert.ToDateTime(dtTime.Rows[0]["DataFinalizare"].ToString());
NrComanda.Text = (dtTime.Rows[0]["OrderID"].ToString());
NumCl.Text = (dtTime.Rows[0]["NumeClient"].ToString());
if (dtTime.Rows[0]["Factstatus"].ToString() == "Nefacturata")
{
radioNefact.Checked = true;
TextFactura.Text = "";
}
else
{
TextFactura.Text = (dtTime.Rows[0]["Factstatus"].ToString());
radioNefact.Checked = false;
}
}
}
}
if (Connection.type == "C")
{
tableLayoutPanel1.Enabled = false;
tableLayoutPanel2.Enabled = false;
tableLayoutPanel5.Enabled = false;
EditOrderList.Enabled = false;
UpdateOrder.Enabled = false;
}
}
public DataTable GetOrderDetails(string editOrder)
{
using (SqlConnection con = new SqlConnection(#"Data Source = GAMEWORK\SQLEXPRESS; Initial Catalog = Tida; Integrated Security = True"))
using (SqlDataAdapter ada = new SqlDataAdapter("SELECT Clienti.NumeClient, Produse.Denumire, Produse.Cantitate, Produse.Dimensiuni, Produse.Comentarii, Produse.NumeMaterial, Produse.NumeFinisaj, IDComenzi.DataInitial,Comenzi.DataFinalizare, Comenzi.Factstatus, Comenzi.Livstatus FROM Comenzi INNER JOIN Clienti ON Comenzi.ClientID = Clienti.IDClient INNER JOIN Produse ON Comenzi.ProductID = Produse.IDProdus INNER JOIN IDComenzi ON Comenzi.OrderID = IDComenzi.IDComanda WHERE OrderID=#OrderID", con))
{
ada.SelectCommand.Parameters.Add("#OrderID", SqlDbType.Int).Value = Convert.ToInt32(editOrder); //ERROR HERE: System.FormatException: 'Input string was not in a correct format.'
DataTable dt = new DataTable();
ada.Fill(dt);
return dt;
}
}

How to set datagridview scroll position in C# winform when enter key is used in keydown event?

I'm having problem setting the vertical scroll position. I have followed this similar question and I get the expected result for CellDoubleClick Event. But for KeyDown Event, where the user will press Enter key, it resets the vertical scroll position at the top
These are my CellDouble Click and KeyDown events.
private void dataGridSrch_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
addToSell();
}
}
private void dataGridSrch_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
addToSell();
}
This is my addToSell function, this function will call after that will update the DataGridView.
public void addToSell()
{
if (dataGridSrch.SelectedRows.Count > 0)
{
DataRow row = (dataGridSrch.SelectedRows[0].DataBoundItem as DataRowView).Row;
if (Convert.ToInt32(row["Stock"].ToString()) > 0)
{
string sellProd = row["Brand"].ToString() + " " + row["Part No."].ToString();
int sellQty = Convert.ToInt32(numSell.Value);
string sellUnit = row["Unit"].ToString();
double sellPrice = double.Parse(row["Price"].ToString()) * sellQty;
double sPrice = double.Parse(row["Price"].ToString());
dataGridSales.Rows.Add(sellProd, sellQty, sellUnit, sellPrice, sPrice, row["Part No."].ToString(), row["Stock"].ToString());
int count = 0;
double total = 0;
for (int i = 0; i < dataGridSales.Rows.Count; i++)
{
total += Convert.ToDouble(dataGridSales.Rows[i].Cells[3].Value);
count += Convert.ToInt32(dataGridSales.Rows[i].Cells[1].Value);
}
lblTotAmt.Text = "Total Amount: " + total.ToString("C2");
lblTotItem.Text = "Total Items: " + count;
amount = total;
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(#"UPDATE [dbo].[products]
SET Stock = Stock - '" + sellQty + "' WHERE [Part No.] = '" + row["Part No."] + "'", conn))
{
cmd.ExecuteNonQuery();
}
conn.Close();
}
>>>>>>>>>>>>>>>>after(); //THIS IS WHERE AFTER FUNCTION IS CALLED
}
else
{
MessageBox.Show("You dont have any stock for the selected item, please restock immediately.", "Please restock", MessageBoxButtons.OK);
}
}
if (dataGridSales.Rows.Count > 0)
{
cmbMOP.Enabled = true;
}
}
And this is my after function.
public void after()
{
string item = cmbItem.Text;
string brand = cmbBrand.Text;
string part = txtPart.Text;
string manu = cmbMan.Text;
string car = cmbCar.Text;
string year = cmbYr.Text;
conn.Open();
{
int index = dataGridSrch.SelectedRows[0].Index;
>>>>>>>>>>>>int scrollPos = dataGridSrch.FirstDisplayedScrollingRowIndex; //GET THE SCROLL POSITION
string sel = #"SELECT * FROM[dbo].[products] WHERE 1=1";
using (SqlCommand cmd = new SqlCommand())
{
if (!string.IsNullOrEmpty(item))
{
sel += " AND Item = #Item";
cmd.Parameters.Add("#Item", SqlDbType.VarChar).Value = item;
}
if (!string.IsNullOrEmpty(brand))
{
sel += " AND Brand = #Brand";
cmd.Parameters.Add("#Brand", SqlDbType.VarChar).Value = brand;
}
if (!string.IsNullOrEmpty(part))
{
sel += " AND [Part No.] = #Part";
cmd.Parameters.Add("#Part", SqlDbType.VarChar).Value = part;
}
if (!string.IsNullOrEmpty(manu))
{
sel += " AND Manufacturer = #Manufacturer";
cmd.Parameters.Add("#Manufacturer", SqlDbType.VarChar).Value = manu;
}
if (!string.IsNullOrEmpty(car))
{
sel += " AND Car = #Car";
cmd.Parameters.Add("#Car", SqlDbType.VarChar).Value = car;
}
if (!string.IsNullOrEmpty(year))
{
sel += " AND Year = #Year";
cmd.Parameters.Add("#Year", SqlDbType.VarChar).Value = year;
}
cmd.CommandText = sel;
cmd.Connection = conn;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
DataView dv = dt.DefaultView;
sda.Fill(dt);
dataGridSrch.DataSource = dt;
dv.Sort = "Item, Brand, Manufacturer, Car, Year, Price ASC ";
dataGridSrch.Columns["Price"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dataGridSrch.Columns["Price"].DefaultCellStyle.Format = "C2";
dataGridSrch.Columns["Stock"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dataGridSrch.Rows[index].Selected = true;
>>>>>>>>>>>>>>>>>>>>dataGridSrch.FirstDisplayedScrollingRowIndex = scrollPos; //AFTER UPDATE SET THE SCROLL POSITION
typeof(DataGridView).InvokeMember("DoubleBuffered", BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty, null,
dataGridSrch, new object[] { true });
}
}
}
conn.Close();
}
I have also change my KeyDown Event to this
private void dataGridSrch_KeyDown(object sender, KeyEventArgs e)
{
int index = dataGridSrch.SelectedRows[0].Index;
int scrollPos = dataGridSrch.FirstDisplayedScrollingRowIndex;
if (e.KeyCode == Keys.Enter)
{
addToSell();
dataGridSrch.Rows[index].Selected = true;
dataGridSrch.FirstDisplayedScrollingRowIndex = scrollPos;
}
}
But still it resets the scroll position.

3 DataGridViews interlinking issues

I am having three Datagridviews in my windows Form. One brings the data of Villages, on clicking any cell, Second Datagridview is populated with Customer Details. On clicking the customer name, third Datagridview must populate and calculate the balance of customer, whether credit is remaining or advance is deposited, now where I am facing problem is the third datagridview.
It specifically throws exception: Object reference set to null.
private void dataGridView3_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
double loansum1 = 0;
double emisum1 = 0;
double dd1 = 0;
double ei1 = 0;
double finalsum = 0;
foreach (DataGridViewRow drr1 in dataGridView3.Rows)
{
if (drr1.Cells[1].Selected == true)
{
string customerid = drr1.Cells[0].Value.ToString();
label1.Text = customerid;
SqlConnection setcon = new SqlConnection(ConfigurationManager.ConnectionStrings["sismanager"].ConnectionString);
using (SqlCommand getsup = new SqlCommand("SELECT Ciid, Cdate, Cparticulars, Ccr, Cdr FROM Customerbills WHERE Cid = #Cid ORDER BY Cdate DESC", setcon))
{
getsup.Parameters.AddWithValue("#Cid", customerid);
SqlDataAdapter drrr = new SqlDataAdapter(getsup);
try
{
setcon.Open();
DataTable data1 = new DataTable();
drrr.Fill(data1);
if (data1.Rows.Count > 0)
{
dataGridView1.DataSource = data1;
dataGridView1.Columns[0].HeaderText = "Bill Number";
dataGridView1.Columns[1].HeaderText = "Bill Date";
dataGridView1.Columns[2].HeaderText = "Particulars";
dataGridView1.Columns[3].HeaderText = "Credit Balance";
dataGridView1.Columns[4].HeaderText = "Cash Balance";
for (int ij = 0; ij < (dataGridView1.Rows.Count); ++ij)
{
dd1 = Double.Parse(dataGridView1.Rows[ij].Cells[3].Value.ToString());
ei1 = Double.Parse(dataGridView1.Rows[ij].Cells[4].Value.ToString());
loansum1 += dd1;
emisum1 += ei1;
}
label4.Text = (Math.Round(loansum1)).ToString();
label5.Text = (Math.Round(emisum1)).ToString();
finalsum = (emisum1 - loansum1);
if (finalsum >= 0)
{
label6.Text = "Rs. " + finalsum + " (Previous Amount Clear)";
}
else
{
label6.Text = "Rs. " + finalsum + " (Previous Amount Due)";
}
}
}
catch (SqlException exx)
{
}
finally
{
setcon.Close();
}
}
}
}
}
The exception error comes at:
dd1 = Double.Parse(dataGridView1.Rows[ij].Cells[3].Value.ToString());
Error Image below; It shows in call stack that the data is coming.

Null Value appear in DataGridView in after new column added

My Datagridview have one name column. I am trying to add one image column with that datagridview. Once I add the image column it made that name column as null. Please refer the below code:
public void call(string usr)
{
user = usr;
queryString = "select NAME 'Name' from ADK_MY_PRODSYSSECGROUP";
try
{
specdataadapter = new SqlDataAdapter(queryString, con);
specds = new DataSet();
con.Open();
specdataadapter.Fill(specds, "REPORT_Table");
dgvdisp.DataSource = specds;
dgvdisp.DataMember = "REPORT_Table";
dgvdisp.Columns[dgvdisp.ColumnCount - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
con.Close();
if (user == "Secgrp")
{
DataGridViewImageColumn set = new DataGridViewImageColumn();
set.Name = "set";
set.HeaderText = "Settings";
dgvdisp.Columns.Insert(1, set);
for (int rows = 0; rows < dgvdisp.Rows.Count; rows++)
{
MessageBox.Show(dgvdisp.Rows[rows].Cells[0].Value.ToString());
}
}
}
catch (Exception ex)
{
DispMessageBox disp = new DispMessageBox("Fail to retrieve data. Please try again");
disp.ShowDialog();
}
}
public void calling()
{
SqlConnection con = new SqlConnection(connetionString);
for (int rows = 0; rows < dgvdisp.Rows.Count; rows++)
{
SqlCommand command = new SqlCommand("select SETTINGS from ADK_MY_PRODSYSSECGROUP where NAME='" + Convert.ToString(dgvdisp.Rows[rows].Cells[0].Value) + "'", con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
if (reader.GetInt32(0) == 1)
{
Image image = Properties.Resources.start;
//set.Image = image;
dgvdisp.Rows[rows].Cells["set"].Value = image;
}
if (reader.GetInt32(0) == 0)
{
Image image = Properties.Resources.finish;
//set.Image = image;
dgvdisp.Rows[rows].Cells["set"].Value = image;
}
}
}
reader.Close();
con.Close();
}
}
Here in the call method, dgvdisp datagridview shows the value, But when I tried to get the value from calling method, the datagridview shows null value when I retrieve name field.
Please suggest...

Changing Quantity value within Datagridview, the price also changes. how possible? which event will do this.CellEndEdit already used

I want to Change Quantity value within Datagridview, it will change price also. how it is possible? which event is for it using C# windows form.CellEndEdit already used by other cell(productname).
private void dataGridViewSalesForm_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
string MatchingProduct = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
for (int i = 0; i < objArrayList.Count; i++)
{
if (objArrayList[i].ToString().ToLower().StartsWith(MatchingProduct.ToLower()))
{
dataGridViewSalesForm.Rows[0].Cells[1].Value = objArrayList[i].ToString();
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading brandname from brandtable*/
string get_strProductName = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
string quantity = "1";
SqlConnection conn = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT T_Inv_Brands.brand_name FROM T_Inv_Products INNER JOIN T_Inv_Brands ON T_Inv_Products.brand_id = T_Inv_Brands.brand_id WHERE T_Inv_Products.prod_name ='" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridViewSalesForm.Rows[0].Cells[2].Value = ds.Tables[0].Rows[0]["brand_name"].ToString();
dataGridViewSalesForm.Rows[0].Cells[3].Value = quantity;
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading retailprice from producttable*/
SqlConnection connection = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT retailprice FROM T_Inv_Products WHERE prod_name = '" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, connection);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridViewSalesForm.Rows[0].Cells[4].Value = Convert.ToDouble(dt.Rows[0]["retailprice"].ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//double quantityload = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[3].Value.ToString());
//double pricefetch = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[4].Value.ToString());
//double result = quantityload * pricefetch;
//dataGridViewSalesForm.Rows[0].Cells[4].Value = result.ToString();
}
You seem to think that you can use an event for one cell or column only. Instead you need to code your events in such a way that all necessary cells and/or columns get their own piece of logic.
It helps to partition your code into smaller pieces with helpful names that document the logic they contain!
Here is an example with two branches, one for a certain cell and one for a certain column. I pass out the DataGridViewCellEventArgs so the functions can access the DataGridView DGV just as the real event can.. Of course you can expand on it as needed:
int quantityColumnIndex = 3; // use your own numbers..
int currencyColumnIndex = 1; // ..and names!!
int currencyRowIndex = 0;
int pricePerUnitColumnIndex = 7;
int totalPriceColumnIndex = 8;
int totalBasePriceColumnIndex = 4;
private void DGV_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == quantityColumnIndex) doPriceCalc(e);
else if (e.ColumnIndex == currencyColumnIndex && e.RowIndex == currencyRowIndex)
doAllCalc(e);
}
void doPriceCalc(DataGridViewCellEventArgs e)
{
// 1st example
DGV[totalPriceColumnIndex, e.RowIndex].Value =
(int)DGV[quantityColumnIndex, e.RowIndex].Value *
(decimal)DGV[pricePerUnitColumnIndex, e.RowIndex].Value;
}
void doAllCalc(DataGridViewCellEventArgs e)
{
// 2nd example
decimal currency = (decimal) DGV[currencyColumnIndex,currencyRowIndex ].Value;
for (int row = 0; row < DGV.Rows.Count; row++)
DGV[pricePerUnitColumnIndex, e.RowIndex].Value =
(decimal)DGV[totalBasePriceColumnIndex, e.RowIndex].Value * currency;
}
Note that I have indexed the columns by their indeices. You may just as well index them by their names, e.g.: DGV[ "PricePerUnit", e.rowIndex]

Categories