Calculation Unit Piece in GridControl error - c#

I have a gridcontrol and in there unitPrice, TotalPrice and Quantity column. When i use this code to calculate unitPrice it calculates the first row and another rows in UnitPrice = 0 Please help?
private void Chillers_Load(object sender, EventArgs e)
{
this.ornekTblTableAdapter.Fill(this.chillersDataSet.OrnekTbl);
InitMDBData();
var row = gridView1.GetFocusedDataRow();
var totalprice = Convert.ToDecimal(row["TotalPrice"]);
var quantity = Convert.ToDecimal(row["Quantity"]);
row["UnitPrice"] = totalprice / quantity;
}

You need a simple foreach loop
foreach(var row in gridView1.Rows)
{
var totalprice = Convert.ToDecimal(row["TotalPrice"]);
var quantity = Convert.ToDecimal(row["Quantity"]);
row["UnitPrice"] = totalprice / quantity;
}
Update: for your special dataGridView try this:
for(int i=0; i< gridView1.RowCount; i++)
{
var totalprice = Convert.ToDecimal(gridView.GetRowCellValue(i, "TotalPrice"));
var quantity = Convert.ToDecimal(gridView.GetRowCellValue(i, "Quantity"));
gridView1.SetRowCellValue(i,"UnitPrice",(totalprice / quantity));
}

You are only changing one row, gridView1.GetFocusedDataRow().
You need to either add the computed value to the original data source, or put a data binding expression in your gridview markup, i.e.
<asp:templatecolumn><%# Eval(((decimal)Container.DataItem["TotalPrice"]) / ((decimal)Container.DataItem["TotalPrice"]) %></asp:templatecolumn>

Related

datagridview cells multiplying and sum the column in textbox

I have a problem in multiplying tow cell of one row and sum one of the column after multiplying in datagridview and show the final result in textbox in C# , please guide me how can I do this enter image description here
private void btnsum_Click(object sender, EventArgs e)
{
int multiplication = 0;
int sum = 0;
for (int i = 0; i < saleDataGridView.Rows.Count; i++)
{
if (saleDataGridView != null)
{
if (int.TryParse(saleDataGridView.Rows[i].Cells[1].Value.ToString(), out sum) && int.TryParse(saleDataGridView.Rows[i].Cells[6].Value.ToString(), out multiplication))
{
int total = sum * multiplication + Convert.ToInt32(saleDataGridView.Rows[i].Cells[1].Value);
// sum += *Convert.ToInt32(saleDataGridView.Rows[i].Cells[6].Value);
txttotal.Text = total.ToString();
}
else {
MessageBox.Show("error");
}
enter image description here
I think it is easy by using Binding DataGridView using generic List.
For example
class MyModel
{
public double Price { get; set; }
public double Quantity { get; set; }
}
Binding this model to DataGridView and calculating totals using LINQ, after click button example:
public partial class Form1 : Form
{
private List<MyModel> myData;
public Form1()
{
InitializeComponent();
myData = new List<MyModel>() { new MyModel() {Price=35000,Quantity=100 }, new MyModel() { Price = 150000, Quantity = 322 } };
dataGridView1.DataSource = myData;
}
private void btnCalc_Click(object sender, System.EventArgs e)
{
var result = myData.Sum(s => s.Price * s.Quantity);
txtBoxTotal.Text = result.ToString();
}
}
Result:
other solution, if you want calculate by using DataGridView Cells:
double result = 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var price = double.Parse(row.Cells[0].Value.ToString());
var quantity = double.Parse(row.Cells[1].Value.ToString());
result += price * quantity;
}
txtBoxTotal.Text = result.ToString();
For your case:
private void btnsum_Click(object sender, EventArgs e)
{
var result = 0;
foreach (DataGridViewRow row in saleDataGridView.Rows)
{
int price, quantity;
if (int.TryParse(row.Cells[1].Value.ToString(), out price) && int.TryParse(row.Cells[6].Value.ToString(), out quantity))
result += price * quantity;
else
MessageBox.Show("error");
}
txttotal.Text = result.ToString();
}
There are numerous ways you can approach this. Obviously you can loop through the grid rows and calculate the total for each row and sum all those values. Or if the grid has a data source, you could loop through those rows/items and get the totals also.
Therefore, since you do not say if the grid has a data source or not, this makes things difficult to suggest a proper solution. Example, if the grid’s underlying data source is a DataTable, then, you could “add” a “Total” “Expression” column to the grid that would calculate the “Price” * “Quantity” value for each row. This would remove one calculation from your code. You could also set the text boxes text to the SUM of all “Total” cells in the DataTable with the DataTable’s Compute function, thus eliminating another calculation you have to code. Any time the grids “Price” or “Quantity” value changes, then, we would update the text box sum total using the data tables Compute function.
Or as Mansur’s answer suggest, you could create a simple class to manage both the grid’s data source in addition to the text boxes data binding. This is the approach used below. In the Item class there would be three properties where “Price” and “Quantity” are both “editable” properties. The third property will be a read only “Total” that will return the “Price” * “Quantity” value.
We could simply make a list of Item objects and it should make things easier, however, I say let’s go one step further and create another Class called ListOfItems it will have two properties. A BindingList of Item objects AND a decimal read only property that returns the SumTotal of ALL the items in the list.
The idea with this class is that we can now bind BOTH the grid AND the TextBox to the “same” DataSource. The grid’s DataMember would be the BindingList of Item objects, and to bind the TextBox we will set its DataMember to the SumTotal property. This should make things much easier as far as calculating each rows total and the total of all rows.
public class Item {
public decimal Price { get; set; }
public int Quantity { get; set; }
public decimal Total => Price * Quantity;
}
public class ListOfItems {
public BindingList<Item> Items { get; set; }
public ListOfItems() {
Items = new BindingList<Item>();
}
public decimal SumTotal => Items.Sum(x => x.Total);
}
However, there is one small issue. If we look at the ListOfItems Class… we can see that SumTotal will reflect the current state of Items List, however if the list changes, then we will still need some mechanism to signal to the text box to “update” the total. In addition, when the grid cell values are changed by the user, there are certain situations where the data in the grid, may not necessarily exist in the underlying data source. In that case the total could be wrong.
These issues (among others) could be resolved if we simply use a BindingSource. If we use a BindingSource and set it’s DataSource to our ListOfItems object, then all we need to do when a cells price or quantity changes is to call the BindingSource’s ResetBinding method and it should update the grid and text box in one step. Even if this was not needed, using a BindingSource in a grid has numerous advantages… like this.
To give this a test, you can create a new winforms solution, and drop a DataGridView along with a TextBox for the sum total onto the form. There are two global variables… the BindingSource and the ListOfItems object. The code below is to generate some test data.
private ListOfItems GetData() {
ListOfItems listOfItems = new ListOfItems();
listOfItems.Items.Add(new Item { Price = 10.50m, Quantity = 2 });
listOfItems.Items.Add(new Item { Price = 1.0m, Quantity = 3 });
listOfItems.Items.Add(new Item { Price = 1.50m, Quantity = 3 });
return listOfItems;
}
The load method to set up everything…
BindingSource bs;
ListOfItems AllItems;
public Form1() {
InitializeComponent();
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
}
private void Form1_Load(object sender, EventArgs e) {
AllItems = GetData();
bs = new BindingSource();
bs.DataSource = AllItems;
dataGridView1.DataSource = bs;
dataGridView1.DataMember = "Items";
textBox1.DataBindings.Add("Text", bs, "SumTotal");
}
Finally, the grids CellValueChanged event to update the text box when a “Price” or “Quantity” cell changes. All we need to do is Reset the binding source for the text box to update.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "Price" ||
dataGridView1.Columns[e.ColumnIndex].Name == "Quantity") {
if (dataGridView1.Rows[e.RowIndex].Cells["Price"].Value != null &&
dataGridView1.CurrentRow.Cells["Quantity"].Value != null) {
if (!string.IsNullOrWhiteSpace(dataGridView1.CurrentRow.Cells["Price"].FormattedValue.ToString()) &&
!string.IsNullOrWhiteSpace(dataGridView1.CurrentRow.Cells["Quantity"].FormattedValue.ToString())) {
bs.ResetBindings(false);
}
}
}
}
Lastly, as suggested earlier, you could do the same thing using a DataTable, by changing the Items property of ListOfItems class to a DataTable and either use LINQ or the DataTable’s Compute function to compute the sum total. In my tests, this will require and extra step, however it is trivial.
I hope this makes sense.
private void button1_Click(object sender, EventArgs e) {
int sum = 0;
for (int i = 0; i < dataGridView1.Rows.Count; i++) {
sum += Convert.ToInt32(dataGridView1.Rows[i].Cells[4].Value);
}
txtTotal.Text = sum.ToString();
}

Compute Subtotal of POS

So I'm creating a project, which is a Point of Sale, like those in fast food chains.
The buttons on my POS is created dynamically, depends on the values from my database, and now I'm having a hard time to compute the subtotal when I change the quantity of each item. I used DataGrid to list all the products ordered by the customer.
I created two buttons which is add and minus that can set the quantity of the selected row in the datagridview, I'm not sure if I got it right but the code is also provided below which computes the price of the selected item multiplied to the quantity.
My problem is, how can I compute the subtotal price, and the total quantity of items in my datagridview everytime I add items in my datagrid or I add or subtract in the quantity of the item.? The subtotal should reflect immediately EVERYTIME I add an item, or add or subtract an item.
Provided is a sample image to understand better what I want to happen in my project.
public 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;
var rate = Convert.ToDouble(row.Cells["SellingPrice"].Value);
row.Cells["TotalPrice"].Value = quantity * rate;
}
private void frmPOS_Load(object sender, EventArgs e)
{
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
add.Click += quantity_change;
minus.Click += quantity_change;
cmd = new MySqlCommand("SELECT * FROM tblmenu", dbConn);
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Button btn = new Button();
btn.Text = rdr["menuName"].ToString();
btn.Name = rdr["menuID"].ToString();
btn.Width = 126;
btn.Height = 80;
btn.Click += delegate
{
dataGridView1.ClearSelection();
MySqlConnection cnn2 = new MySqlConnection(sqlConn.connString);
cnn2.Open();
cmd = new MySqlCommand("SELECT menuName, menuPrice FROM tblmenu WHERE menuID = #id", cnn2);
cmd.Parameters.AddWithValue("#id", btn.Name);
MySqlDataReader rdr2 = cmd.ExecuteReader();
while (rdr2.Read())
{
//I added the item in my datagridview, with the button name, 1 = 1quantity, and Selling Price
dataGridView1.Rows.Add(rdr2.GetString("menuName").ToUpper(), 1, rdr2.GetDouble("menuPrice"));
}
//I copied the value of Selling Price Column to the Total Price Column in this part
foreach (DataGridViewRow row in dataGridView1.Rows)
{
value = row.Cells["SellingPrice"].Value.ToString();
row.Cells["TotalPrice"].Value = value;
}
};
if (rdr["menuAvailability"].ToString() == "yes")
{
if (rdr["menuCategory"].ToString() == "Sandwiches")
{
flpSandwiches.Controls.Add(btn);
}
else if (rdr["menuCategory"].ToString() == "Appetizers")
{
flpAppetizers.Controls.Add(btn);
}
}
}
rdr.Close();
}
What I can see in your quantity_change method:
row.Cells["TotalPrice"].Value = quantity * rate;
for me it is subtotal for given product.
You you wan't to calculate total price of whole order (all products in data grid) you need to sum all subtotals for all products.
For example, at the end of quantity_Change:
double Total=0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
Total+=row.Cells["TotalPrice"].Value;
}
// now you can set this value for example label under data grid
labelTotal.Text = Total.ToString();

How to counting total number of rows greater than zero in gridview in ASP.NET

I have grid view in asp.net page using SQLDataSource.
I want display total number of rows greater than zero in label.Text.
(my column is column of price and I want count rows that price is greater than zero
how can i do that
i try this code for total number of rows:
int totalRows = e.AffectedRows;
thanks
You will have to use linq for comparing the values with price > 0
for eg:-
var count = objVar.Where(x=>x.price > 0).count();
In order to read directly from cells in the GridView, I used a method named GetPrice() which returns a list of all prices in a specific column.
Note: You should specify which column is related to Price in the GridView, so the index(Zero-Based) of Price column must be set in the PriceColumnIndex constant variable.
protected void Page_Load(object sender, EventArgs e)
{
List<double> lstPrice = GetPrice();
double dblPriceSum = lstPrice.Where(p => p > 0).Sum();
lblCount.Text = string.Format("{0:#,##0 Rls}", dblPriceSum);
}
private List<double> GetPrice()
{
const int PriceColumnIndex = 0;
List<double> resList = new List<double>();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
string strPrice = GridView1.Rows[i].Cells[PriceColumnIndex].Text;
double dblPrice;
bool blIsParsable = double.TryParse(strPrice, out dblPrice);
if (blIsParsable)
resList.Add(dblPrice);
}
return resList;
}
Good luck.

How to multiply data of two columns for third column in datagridview

I want to multiply the data of two columns and show it in the third column.
For example:
1st Column: Quantity
2nd Column: Rate
3rd Column: Price
I want to multiply as user enters the data for quantity and rate like Quantity=2, rate=50automatically in price column I want 100 to be appear.
Simultaneously I want to division as user enters the data for quantity and rate like Price=100, rate=50automatically in Quantity column I want 2 to be appear.
And
when a user enters the data for quantity and rate like Price=100, Quantity=2automatically in Rate column I want 50 to be appear.
This three will happen in a same datagridview. User only enter any two field within this three and third will come automatically.
Using C#, VS2008, SQL 2008
private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
int quantity,rate;
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
if(int.TryParse(dataGridView2.Rows[i].Cells[1].Value.ToString(), out quantity) && int.TryParse(dataGridView2.Rows[i].Cells[2].Value.ToString(), out rate))
{
int price = quantity * rate; dataGridView2.Rows[i].Cells[3].Value = price.ToString();
}
}
}
I write this code. There shows a error. Object reference not set to an instance of an object on
if(int.TryParse(dataGridView2.Rows[i].Cells[1].Value.ToString(), out quantity) && int.TryParse(dataGridView2.Rows[i].Cells[2].Value.ToString(), out rate))
this line.
I want to do like this. User can fill any 2 field among this 3. And third will take automatically.
handle the CellEndEdit event of your gridview. And in that event calculate and assign the value to the third column
something like
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
int quantity,rate;
if (int.TryParse(dataGridView1.Rows[e.RowIndex].Cells["quantity"].Value.ToString(), out quantity) && int.TryParse(dataGridView1.Rows[e.RowIndex].Cells["rate"].Value.ToString(), out rate))
{
int price = quantity * rate;
dataGridView1.Rows[e.RowIndex].Cells["price"].Value = price.ToString();
}
}
This is the solution for you.
double s = Convert.ToDouble(DataGridShowAddedProducts.Rows[0].Cells[2].Value);
double s1 = Convert.ToDouble(DataGridShowAddedProducts.Rows[0].Cells[2].Value);
double s13 = s1 * s;
MessageBox.Show(s13.ToString());
decimal s=0, s1=0,s13 = 0;
for (int j = 0; j< dgvsaledetails.Rows.Count; ++j)
{
s = Convert.ToDecimal(dgvsaledetails.Rows[j].Cells[6].Value);
s1 = Convert.ToDecimal(dgvsaledetails.Rows[j].Cells[10].Value);
s13 = s * s1;
dgvsaledetails.Rows[j].Cells["amount"].Value = s13.ToString();
}
usually see error parameter column
So dont use header name of column but only for column name as see
decimal qty = 0, price = 0, amount = 0;
for (int j = 0; j < dataGridView2.Rows.Count; ++j)
{
// cloumn9=qty
qty = Convert.ToDecimal(dataGridView2.Rows[j].Cells["Column9"].Value);
// column4 = price
price = Convert.ToDecimal(dataGridView2.Rows[j].Cells["Column4"].Value);
amount = qty * price;
// cloumn7 = amount
dataGridView2.Rows[j].Cells["Column7"].Value = s13.ToString();
}

Summing GridView column values

I have a "time duration" column in a grid view, and I wish to sum that particular column in C# and publish the total time taken at a label named Total Time. How can I do this?
Sample code:
int sum = 0;
for (int i = 0; i < dgTestSteps.SelectedColumns.Count; ++i)
{
sum += Convert.ToInt32(dgTestSteps.SelectedColumns.Count.ToString());
//sum += Convert.ToInt32(dgTestSteps.Rows[i].Cells[1].Value);
}
lblTotalTime.Text = sum.ToString();
int sum = 0;
for (int i = 0; i < dgTestSteps.Rows.Count; ++i)
{
sum += Int.Parse(dgTestSteps.Rows[i].Cells[1].Value.ToString());
}
lblTotalTime.Text = sum.To String();
It seems true! Is there any problem with this?
I do this by aggregating the column row values in a class variable thusly:
Code behind:
protected void ItemsGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Get the row variable values
var rowView = (DataRowView)e.Row.DataItem;
var itemId = Convert.ToInt32(rowView["ItemID"]);
var skuId = Convert.ToInt32(rowView["ItemSkuID"]);
var quantity = Convert.ToInt32(rowView["Quantity"]);
// Instantiate instances of the relevant classes
var item = new Item(itemId);
var sku = new Sku(skuId);
var itemPrice = String.Format("{0:n2}", (item.Price + sku.PriceAdj));
var itemPriceLiteral = (Literal)e.Row.FindControl("ItemPrice");
if (itemPriceLiteral != null)
{
itemPriceLiteral.Text = itemPrice;
}
var itemExtendedPriceLiteral = (Literal)e.Row.FindControl("ItemExtendedPrice");
if (itemExtendedPriceLiteral != null)
{
var extendedPrice = price * quantity;
itemExtendedPriceLiteral.Text = String.Format("{0:n2}", extendedPrice);
// Increment the extended price
_totalExtendedPrice += extendedPrice;
}
}
}
// Lots of stuff omitted from this method for clarity
public void GetSummary()
{
// Set the text property of the total literal below the GridView
OrderTotal.Text = string.Format((HttpUtility.HtmlDecode(
(string)GetGlobalResourceObject("ShopStrings", "UsdPrice"))),
_totalExtendedPrice);
}
OrderTotal.Text is localized but you can easily format it without using resources.
You can use this but you should know that number of columns start with 0 and goes up with 1
int sum = 0;
for (int i = 0; i < dgTestSteps.Rows.Count; ++i)
{
sum += Convert.ToInt32(dgTestSteps.Rows[i].Cells[0].Value);
}
lblTotalTime.Text = sum.ToString();
I tried this and has no problem

Categories

Resources