Copy Data from One DataGridView to Another Using C# and Vb.Net

← PrevNext →

Do you know we can transfer single or multiple rows of data from one DataGridView control to another with a just a few lines of Code? Yes, we can do it. However, why would someone do that? There are many valid reasons to do it. However recently, we came across a situation where we had to upgrade details of existing records with new details without changing the original one.

Therefore, we came up with a simple solution. Usually, a DataGridView control will display a huge collection of data in tabular format. If a particular row’s data needs to be modified, we will double click the row and switch (or transfer) data into another DataGridView for modification.

Now, let us see how we can do this.

01) Fetch data from a database table and populate it in a DataGridView (Parent Grid).
02) Double click a Row or Cell to copy data from Parent Grid to Child Grid and show it.

DataGridView - Copy Row

Start Microsoft Visual Studio and select a New Project from File (Left Top Menu). From the New Project templates, select Windows Forms Application and click OK.

01) A new project appears with a Blank Form. Click the Toolbox button and from the list of tools Double Click to add a Panel control on the form. (Panel1)

02) Drag a DataGridView control and drop it on the Panel. Name the DataGridView as DGVParent. Set the grid’s Drop property as Fill.

03) Drag and drop another Panel (Panel2) from the Toolbox and drop it on the Parent Grid. Set this panel’s Visible property as false.

04) Finally, drag another DataGridView control and drop it on the Second Panel (Panel2).

Note: The Panels we have added on the form, actually works as a container. You can use the Group Box control either.

The second panel will remain hidden, till the user Double Clicks one of the parent grid’s rows. This will show the Panel2 with the Child Grid below the row which has been clicked.

Code Behind (C#)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace DataGridView
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            PopulateData();
        }

        // POPULATE AND SHOW EMPLOYEE DETAILS.

        private void PopulateData()
        {
            DataTable dt = new DataTable();
            using (SqlConnection con = new SqlConnection("Data Source=DNA;Persist Security Info=False;" + 
                "Initial Catalog=DNA_CLASSIFIED;User Id=sa;Password=;Connect Timeout=30;"))
            {

                string sQuery = "SELECT EmpID, EmpName Employee, PresentAddress Address, 
                    Email FROM dbo.EmployeeDetails";

                using (SqlCommand cmd = new SqlCommand(sQuery))
                {
                    SqlDataAdapter sda = new SqlDataAdapter();
                    cmd.Connection = con;
                    con.Open();
                    sda.SelectCommand = cmd;
                    sda.Fill(dt);

                    DGVParent.DataSource = dt;      // BIND DATABASE WITH DataGridView.
                    DGVParent.Columns["EmpID"].Visible = false;		// HIDE FIRST COLUMN (EMP ID).

                    // ADD SOME COLOR.
                    DGVParent.GridColor = Color.FromArgb(211, 222, 229);
                    DGVParent.BackgroundColor = Color.Wheat;

                    DGVParent.RowsDefaultCellStyle.BackColor = Color.AliceBlue;
                    DGVParent.RowsDefaultCellStyle.SelectionBackColor = Color.CornflowerBlue;
                    DGVParent.RowsDefaultCellStyle.SelectionForeColor = Color.White;
                }
            }
        }

        // COPY DATA FROM PARENT GRID TO CHILD GRID.
        private void DGVParent_CellDoubleClick(object sender, 
            System.Windows.Forms.DataGridViewCellEventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            if (Convert.IsDBNull(DGVParent[1, DGVParent.CurrentRow.Index].Value)) 
            {
                string sEmpDetailsToUpdate = DGVParent[1, DGVParent.CurrentRow.Index].Value.ToString();
                lblModify.Text = "Showing details of " + sEmpDetailsToUpdate + " in another DataGridView";

                if (!string.IsNullOrEmpty(DGVParent[1, DGVParent.CurrentRow.Index].Value.ToString())) 
                {
                    int x = 0;
                    int y = 0;
                    int w = 0;
                    int h = 0;
                    Rectangle rect = default(Rectangle);

                    rect = DGVParent.GetCellDisplayRectangle(DGVParent.CurrentCell.ColumnIndex, 
                    DGVParent.CurrentRow.Index, false);

                    x = 20;
                    y = rect.Y + DGVParent.Top + rect.Height;

                    w = DGVParent.Width - 37;

                    h = Panel2.Height;
                    Panel2.SetBounds(x, y, w, h);

                    // SHOW THE PANEL WITH THE CHILD GRID JUST BELOW THE SELECTED ROW.
                    Panel2.Visible = true;

                    Application.DoEvents();
                    DGVChild.Rows.Clear();
                    DGVChild.Columns.Clear(); 			// CLEAR DETAILS OF CHILD GRID.

                    // GET COLUMNS FROM THE PARENT GRID AND ADD IT TO THE CHILD GRID.
                    foreach (DataGridViewColumn DGV_Parents_Column in DGVParent.Columns) 
                    {
                        DGVChild.Columns.Add((DataGridViewColumn)DGV_Parents_Column.Clone());
                    }

                    DataGridViewRow row = new DataGridViewRow();

                    for (int iCnt = 0; iCnt <= DGVParent.Rows.Count - 1; iCnt++) 
                    {
                        if (DGVParent.Rows[iCnt].Cells[1].Value == (sEmpDetailsToUpdate) 
                        {
                            row = (DataGridViewRow)DGVParent.Rows[iCnt].Clone();

                            int iColIndex = 0;

                            foreach (DataGridViewCell cell in DGVParent.Rows[iCnt].Cells) {
                                row.Cells[iColIndex].Value = cell.Value;
                                iColIndex += 1;
                            }

                            DGVChild.Rows.Add(row);
                            break;      // NO MATCHES FOUND. BAIL OUT.
                        }
                    }

                    DGVChild.Focus();  // SET FOCUS ON THE CHILD.
                }
            }
            Cursor.Current = Cursors.Default;
        }

        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, 
            System.Windows.Forms.Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                //HIDE THE SECOND PANEL. (THE PANEL WITH THE CLILD GRID)
                if (Panel2.Visible == true) { Panel2.Visible = false; return true; }
            }
        }
    }
}
Code Behind (Vb.Net)
Option Explicit On

Imports System.Data.SqlClient

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        PopulateData()
    End Sub

    ' POPULATE AND SHOW EMPLOYEE DETAILS.

    Private Sub PopulateData()

        Dim dt As DataTable = New DataTable

        Using con As SqlConnection = New SqlConnection("Data Source=DNA;Persist Security Info=False;" & _
                "Initial Catalog=DNA_CLASSIFIED;User Id=sa;Password=;Connect Timeout=30;")

            Dim sQuery As String = "SELECT EmpID, EmpName Employee, PresentAddress Address, 
                Email FROM dbo.EmployeeDetails"

            Using cmd As SqlCommand = New SqlCommand(sQuery)
                Dim sda As SqlDataAdapter = New SqlDataAdapter
                cmd.Connection = con : con.Open()
                sda.SelectCommand = cmd
                sda.Fill(dt)

                With DGVParent
                    .DataSource = dt                   ' BIND DATABASE WITH DataGridView.
                    .Columns.Item("EmpID").Visible = False      ' HIDE FIRST COLUMN (EMP ID).

                    ' ADD SOME COLOR.
                    .GridColor = Color.FromArgb(211, 222, 229) : .BackgroundColor = Color.Wheat

                    .RowsDefaultCellStyle.BackColor = Color.AliceBlue
                    .RowsDefaultCellStyle.SelectionBackColor = Color.CornflowerBlue
                    .RowsDefaultCellStyle.SelectionForeColor = Color.White
                End With
            End Using
        End Using
    End Sub

    ' COPY DATA FROM PARENT GRID TO CHILD GRID.

    Private Sub DGVParent_CellDoubleClick(ByVal sender As Object, 
            ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGVParent.CellDoubleClick

        Cursor.Current = Cursors.WaitCursor

        With DGVParent
            If Not IsDBNull(.Item(1, .CurrentRow.Index).Value()) Then

                Dim sEmpDetailsToUpdate As String = .Item(1, .CurrentRow.Index).Value()
                lblModify.Text = "Showing details of " & sEmpDetailsToUpdate & " in another DataGridView"

                If .Item(1, .CurrentRow.Index).Value() <> "" Then

                    Dim x, y, w, h As Integer
                    Dim rect As Rectangle

                    With DGVParent
                        rect = .GetCellDisplayRectangle(.CurrentCell.ColumnIndex, .CurrentRow.Index, False)
                        x = 20 : y = rect.Y + .Top + rect.Height

                        w = .Width - 37
                    End With

                    With Panel2
                        h = .Height
                        .SetBounds(x, y, w, h)
                        .Visible = True         ' SHOW THE PANEL WITH THE CHILD GRID JUST BELOW THE SELECTED ROW.
                    End With

                    Application.DoEvents()
                    With DGVParent
                        DGVChild.Rows.Clear() : 
                        DGVChild.Columns.Clear()   ' CLEAR DETAILS OF CHILD GRID.

                        ' GET COLUMNS FROM THE PARENT GRID AND ADD IT TO THE CHILD GRID.
                        For Each DGV_Parents_Column As DataGridViewColumn In .Columns
                            DGVChild.Columns.Add(DirectCast(DGV_Parents_Column.Clone(), DataGridViewColumn))
                        Next

                        Dim row As New DataGridViewRow()

                        For iCnt As Integer = 0 To .Rows.Count - 1
                            If Trim(.Rows(iCnt).Cells(1).Value) = Trim(sEmpDetailsToUpdate) Then
                                row = DirectCast(.Rows(iCnt).Clone(), DataGridViewRow)

                                Dim iColIndex As Integer = 0
                                For Each cell As DataGridViewCell In .Rows(iCnt).Cells
                                    row.Cells(iColIndex).Value = cell.Value
                                    iColIndex += 1
                                Next
                                DGVChild.Rows.Add(row)

                                ' NO MATCHES FOUND. BAIL OUT.
                                Exit For
                            End If
                        Next

                        DGVChild.Focus()            ' SET FOCUS ON THE CHILD.
                    End With
                End If
            End If
        End With
        Cursor.Current = Cursors.Default
    End Sub

    ' PRESS ESCAPE KEY TO HIDE THE CHILD GRID.

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, 
        ByVal keyData As System.Windows.Forms.Keys) As Boolean

        If keyData = Keys.Escape Then

            'HIDE THE SECOND PANEL. (THE PANEL WITH THE CLILD GRID)
            If Panel2.Visible = True Then Panel2.Visible = False : Return True

        End If
    End Function

End Class

Well, that's it. Hope you find this post and its examples useful. Thanks for reading.

← PreviousNext →