473,406 Members | 2,745 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

How to copy rows from one DataGridView to another?

BRawn
28
Hi guys,

I'm struggling to copy rows from one DataGridView to another. This may sound redundant but it's necessary for my Orders project. I have 3 DataGridViews on one form.

The first DataGridView gets populated from my database with the product and total available stock. The second DataGridView is sort of a basket...so, when an item is selected from the first DataGridView, the item gets added to the second DataGridView and there's an editable column in the second DataGridView in which the user can enter an amount they want of the product in question.

The third one is just for show. It displays the product and the remaining stock quantity (what there was minus the amount entered by the user).

My problem is this: My item adds fine from the 1st DataGridView to the second, but when I add more than one item and edit the quantities, it doesn't subtract from the correct product, so I'm now trying to copy the rows of my 2nd DataGridView to my 3rd one and try in baby steps, but that's not going too well. Here's what I've tried already:

Expand|Select|Wrap|Line Numbers
  1.  
  2. private void copyDGVRows()
  3.         {
  4.             dgvProductsAfterOrders.Rows.Clear();
  5.             for (int i = 0; i <= dgvLineItems.Rows.Count; i++)
  6.             {
  7.                 dgvProductsAfterOrders.Rows[i].Cells[i].Value = dgvLineItems.Rows[i].Cells[i].Value;
  8.                 //dgvProductsAfterOrders.Rows.Add(i + 1);
  9.             }
  10.         }
  11.  
  12.         private void copyDGVRows()
  13.         {
  14.             dgvProductsAfterOrders.Rows.Clear();
  15.             if (dgvLineItems.Rows.Count == 0)
  16.             {
  17.                 return;
  18.             }
  19.             else
  20.             {
  21.                 foreach (DataGridViewRow row in dgvLineItems.Rows)
  22.                 {
  23.                     row.Cells[1].Clone();
  24.                     for (int i = 0; i < row.Cells.Count; i++)
  25.                     {
  26.                         dgvProductsAfterOrders.Rows[i].Cells[1].Value = row;
  27.                         //dgvProductsAfterOrders.Rows.Add(row);
  28.                     }
  29.                 }
  30.             }
  31.         }
  32.  
  33.         private void copyDGVRows(DataGridView dataGridView, ArrayList rowsToCopy)
  34.         {
  35.             for (int i = 0; i < rowsToCopy.Count; i++)
  36.             {
  37.                 DataGridViewRow row = new DataGridViewRow();
  38.                 row = (DataGridViewRow)dataGridView.Rows[Convert.ToInt32(rowsToCopy[i])].Clone();
  39.  
  40.                 for (int j = 0; j < row.Cells.Count; j++)
  41.                 {
  42.                     row.Cells[j].Value = dataGridView.Rows[Convert.ToInt32(rowsToCopy[i])].Cells[j].Value;
  43.                     dataGridView.Rows.Add(row);
  44.                 }
  45.             }
  46.         }
  47.  
  48.         private void populate3rdGrid()
  49.         {
  50.             dgvProductsAfterOrders.Rows.Clear();
  51.             for (int i = 0; i < dgvLineItems.Rows.Count; i++)
  52.             {
  53.                 if (dgvProductsAfterOrders.Rows[i].Cells[0].Value != null)
  54.                 {
  55.                     dgvProductsAfterOrders.Rows.Add();
  56.                     for (int j = 0; j < dgvLineItems.Rows.Count; j++)
  57.                     {
  58.                         dgvProductsAfterOrders.Rows[i].Cells[j].Value = dgvLineItems.Rows[i].Cells[j].Value;
  59.                     }
  60.                 }
  61.             }
  62.         }
  63.  
  64.  
Nothing seems to be working...any ideas?
Oct 20 '10 #1
2 13899
Christian Binder
218 Expert 100+
Maybe it's better thinking about this from the beginning.

First of all we define what we want:
  • read available products from database
  • put products into basket
  • set/change quantity from products in basket
  • show remaining products (available minus basket)

So we need 3 DGVs, calling them dataGridViewAvailable, dataGridViewBasket, dataGridViewRemaining.

Then we need a Product, so we define a class for it, having a property Name which represents e.g. the product-name.
Expand|Select|Wrap|Line Numbers
  1. public class Product {
  2.   public string Name { get; set; }
  3.  
  4.   public Product(string name) {
  5.     Name = name;
  6.   }
  7.  
  8.   public override string ToString() {
  9.     return Name;
  10.   }
  11. }
  12.  
The next thing we need is a representation of quantities of products, therefore we create another class, having Products and Quantities.
Expand|Select|Wrap|Line Numbers
  1. public class OrderItem {
  2.   public Product Product { get; set; }
  3.   public int Quantity { get; set; }
  4.  
  5.   public OrderItem(Product product, int quantity) {
  6.     Product = product;
  7.     Quantity = quantity;
  8.   }
  9. }
  10.  
After that, we need collections, which hold the available, selected/basket and remaining OrderItems. BindingList<OrderItem> are proper for that.
Expand|Select|Wrap|Line Numbers
  1.     BindingList<OrderItem> _availableProducts = new BindingList<OrderItem>();
  2.     BindingList<OrderItem> _basketProducts = new BindingList<OrderItem>();
  3.     BindingList<OrderItem> _remainingProducts = new BindingList<OrderItem>();
  4.  
To show the contents of this lists to the user, we bind them to the DGVs (at initialization/constructor), using the DataSource-property.
Expand|Select|Wrap|Line Numbers
  1. dataGridViewAvailable.DataSource = _availableProducts;
  2. dataGridViewBasket.DataSource = _basketProducts;
  3. dataGridViewRemaining.DataSource = _remainingProducts;
  4.  
This forces the DataGridView to create a column for each property (of OrderItem), so we have two columns Product and Quantity.

Now it's time to fill our _availableProducts from database-data. I've created a test-method which I call in constructor after data-binding.
Expand|Select|Wrap|Line Numbers
  1. void FillAvailable() {
  2.   //Here the data would come from database
  3.   _availableProducts.Add(new OrderItem(new Product("P1"), 100));
  4.   _availableProducts.Add(new OrderItem(new Product("P2"), 250));
  5. }
  6.  
At this stage it should work that in the first DGV the right values are showing.

When I double-click a cell in my first DGV, I want to add a OrderItem to my second DGV.
Each dgv-row has a corresponding DataBoundItem thich is in our case of type OrderItem.
We take this order-item, extract the product and create a new order-item with that product and a default quantity of zero
which we than add to the basket.
Expand|Select|Wrap|Line Numbers
  1. //designer-created event-handler for CellDoubleClick
  2. void dataGridViewAvailable_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
  3.   if (e.RowIndex != -1) {
  4.     OrderItem order = dataGridViewAvailable.Rows[e.RowIndex].DataBoundItem as OrderItem;
  5.     _basketProducts.Add(new OrderItem(order.Product, 0));
  6.   }
  7. }
  8.  
Now the whole work is nearly done. Looking back to the list on this thread's beginning, there is just one point missing, namely showing the remaining products.
For this purpose we create an update-method. This method summarizes all basket-orderitem's quantities (per Product) and deduct this sum
from the available product-quantity.
This can be done using some for/foreach loops and temporary lists (to group equal products).
For reasons of lazyness, I used some Linq.
Expand|Select|Wrap|Line Numbers
  1. void UpdateRemaining() {
  2.   _remainingProducts.Clear();
  3.   foreach (var remainingProduct in from order in _basketProducts
  4.                                    group order by order.Product into grp
  5.                                    join availableProduct in _availableProducts on grp.Key equals availableProduct.Product
  6.                                    select new OrderItem(grp.Key, availableProduct.Quantity - grp.Select(o => o.Quantity).Sum()))
  7.     _remainingProducts.Add(remainingProduct);
  8. }
  9.  
The very last thing is to call this update-method when the user changes the amount of products in basket,
simply we can use the CellValueChanged-event of dataGridViewBasket after creating it with the designer.

Expand|Select|Wrap|Line Numbers
  1. private void dataGridViewBasket_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
  2.   UpdateRemaining();
  3. }
  4.  
Now the base-functionality is provided. The next steps would be increase user-friendlyness, stability and so on.
Hope this helps for the beginning :-)
Oct 20 '10 #2
BRawn
28
Thanks Chris. I'm gonna give this a go...tomorrow though coz it's almost hometime for me :)

In the meantime I've devised another way around this to refresh the 3rd DataGridView's data every time the "basket's" amount cells were changed. This is what I did:

Expand|Select|Wrap|Line Numbers
  1.  
  2. private void CalculateAvailableStock()
  3.         {
  4.             DataTable dataTable = new DataTable();
  5.             DataColumn datacolumn1 = new DataColumn("Product Name", typeof(System.String)); // string FirstC=”column1″
  6.             DataColumn datacolumn2 = new DataColumn("Available Quantity (After Order)", typeof(System.String)); // string SecondC=”column2″
  7.             dataTable.Columns.Add(datacolumn1);
  8.             dataTable.Columns.Add(datacolumn2);
  9.  
  10.             foreach (DataGridViewRow lineItemsRow in dgvLineItems.Rows)
  11.             {
  12.                 int total = 0;
  13.                 DataRow dr = dataTable.NewRow();
  14.  
  15.                 foreach (DataGridViewRow productsBeforeOrdersRow in this.dgvProductsBeforeOrders.Rows)
  16.                 {
  17.                     if (lineItemsRow.Cells[1].Value.ToString() == productsBeforeOrdersRow.Cells[1].Value.ToString())
  18.                     {
  19.                         int orderedQuantity = 0;
  20.                         int availableQuantity = 0;
  21.  
  22.                         orderedQuantity = int.Parse(lineItemsRow.Cells[2].Value.ToString());
  23.                         availableQuantity = int.Parse(productsBeforeOrdersRow.Cells[2].Value.ToString());
  24.                         total = availableQuantity - orderedQuantity;
  25.                     }
  26.                 }
  27.                 dataTable.Rows.Add(lineItemsRow.Cells[1].Value.ToString(), total);
  28.             }
  29.             dgvProductsAfterOrders.DataSource = dataTable;
  30.         }
  31.  
  32.  
It's probably not best practices but it works, although I think for practicality I'll give your method a go tomorrow as I like the way you use your objects.

Thanks again :)
Oct 20 '10 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

14
by: sdowney717 | last post by:
Using the the NumId from TitleData, I would like to delete the corresponding row in Bookdata using pure SQL. I want it to delete all rows in bookdata where the Titledata.NumID is a match to...
1
by: | last post by:
can all rows from one datatable be copied to another easily without actually traversing each row in the datatable? Thanks for your valuable replies.
0
by: Mansi | last post by:
I'm trying to automate excel via C# and having trouble converting the following code to C#: Rows("12:12").Select Selection.Copy Selection.Insert Shift:=xlDown Application.CutCopyMode = False ...
1
by: J. Babe | last post by:
I was wondering how to add the first 20 rows from one datatable to another datatable without getting the error: This row already belongs to another table
5
by: Nathan Sokalski | last post by:
I am writing an ASP.NET application in which I need to copy DataRows from one DataTable to another. When I use code such as the following: temprows = nodes.Select("state='PA'")...
0
by: carlostol | last post by:
Hello, How can i copy a selected DataGridViewRow who has been clicked to another DataGridView Control in a dinamyc way? I have this code on a button_click event: DataGridViewRow r =...
1
by: byrd48 | last post by:
Hi, am attempting to create a DataTable by copying a table from a data set, then filter the rows as follows: DataTable dt = DataSet1.Tables.Copy; DataRow dr = dt.Select("myexpression"); ...
9
by: sitko | last post by:
Hi, I have an Order tracking spreadsheet that I need help with. I have a 2 worksheets "Open", and "Closed". I have entries on the "Open" sheet which may or may not be grouped together. I've...
4
by: MAdcock | last post by:
Hi, I have created an excel program which creates 65 or more (nneds to be unlimited) customised letters for clients. The macro uses VLOOKUP to change the details within the letter and copies /...
0
by: LSGKelly | last post by:
I have a spreadsheet that has an employee name and a date range, beginning date, ending date. Within that spreadsheet, I have the columns Monday - Friday. I need to pull data into the Monday -...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.