Last updated: 19th June 2024
Do you know you can transfer single or multiple rows of data from one DataGridView control to another with few lines of code? Yes, you can do it and method is very simple. But, why would someone do that? There are many reasons to do it. I recently 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.
Follow these steps.
Start Microsoft Visual Studio and select "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" (or press Ctrl+Alt+X keys) and from the list "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 "second panel" (panel2) with the Child Grid below the row which has been clicked.
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; } } } } }
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