473,703 Members | 2,679 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to copy rows from one DataGridView to another?

BRawn
28 New Member
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 13955
Christian Binder
218 Recognized Expert New Member
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 dataGridViewAva ilable, dataGridViewBas ket, dataGridViewRem aining.

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<Ord erItem> 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 _availableProdu cts 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 CellValueChange d-event of dataGridViewBas ket 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 New Member
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
16247
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 bookdata.id The two tables are linked in that the NumId of table Titledata is identical to the Id of table bookdata. I can, using ADO, loop thru deleting one by one but I would like to do this in a pure SQL statement. Is this possible? Any help is...
1
365
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
1311
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 This code was recorded by the macro in excel. Essentially, what I did was select the entire row 12. Then selected copy. Then I selected "Insert
1
1866
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
2464
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'") temptable.Clear() For Each row As DataRow In temprows temptable.Rows.Add(row) Next
0
1398
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 = dg1.Rows; dg2.Rows.Add(r); <---------
1
1592
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"); dt.Rows.Clear();
9
16769
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 called the rows :Parents and Children. There are basically 3 types of rows. Parents with Children, Parents without Children, and Children. I have a reference cell for each row, where I identify what type of row it is, "-1" = Child, "0" = Parent with...
4
2899
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 / moves the work sheet to another "template file" which contains printing macros etc. Each new worksheet is subsequently renamed to the Client ID reference. The program is meant to do all applicable clients letters and then saves the template...
0
970
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 - Friday columns based on the employee name and that date range from another spreadsheet. The date column in the other speadsheet is called "DueDate" and the employee column is called "Assigned". The column I would like to return is called "Process". ...
0
8739
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9234
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9089
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8983
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7832
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6575
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4412
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3107
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2406
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.