none
how to PASTE (Ctrl+V, Shift+Ins) the data from clipboard to DataGridView (DataGridView1) C# RRS feed

  • General discussion

  • Hi there,

    I was googling how to paste to DataGridView in C# from clipboard, an info, copied from Excel, and didn't find full answer.

    Collected couple of threads from forums and came up with this answer,

    hope it will make someones life easier.

    You dont have to understand the code just copy and paste

    //for example you have a form name=form1 and datagridview name=grid

    //what you have to do?

    //change the property of your form "keypreview=true"

    //double click on the KeyUp method of your form  and copy paste the code below

    //thats it, you dont have to do anything with datagridview except changing its name=grid in the property window

    //_______________________________________________________________________________________________________________

    private void form1_KeyUp(object sender, KeyEventArgs e)

    {

      //if user clicked Shift+Ins or Ctrl+V (paste from clipboard)

      if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))

      {

      char[] rowSplitter = { '\r', '\n' };

      char[] columnSplitter = { '\t' };

      //get the text from clipboard

      IDataObject dataInClipboard = Clipboard.GetDataObject();

      string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);

      //split it into lines

      string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);

      //get the row and column of selected cell in grid

      int r = grid.SelectedCells[0].RowIndex;

      int c = grid.SelectedCells[0].ColumnIndex;

      //add rows into grid to fit clipboard lines

      if (grid.Rows.Count < (r + rowsInClipboard.Length))

      {

      grid.Rows.Add(r + rowsInClipboard.Length - grid.Rows.Count);

      }

      // loop through the lines, split them into cells and place the values in the corresponding cell.

      for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)

      {

      //split row into cell values

      string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);

               //cycle through cell values

      for (int iCol = 0; iCol < valuesInRow.Length; iCol++)

      {

                //assign cell value, only if it within columns of the grid

      if (grid.ColumnCount-1 >= c + iCol)

      {

      grid.Rows[r + iRow].Cells[c + iCol].Value = valuesInRow[iCol];

      }

      }

      }

      }

    }

    //_______________________________________________________________________________________________________________

    Any comments and improvements, welcome.

    Thanks

    Dil

    Monday, November 13, 2006 12:49 PM

All replies

  •  

    Can you please suggest me how t use the same code on a user control, as the user control doesnt haver the KeyPreview property?
    Wednesday, September 17, 2008 8:19 AM
  • I presume yoru user control has a DataGridView, if so you can use KeyUp method of your grid. Be aware that whichever's KeyUp method is used, that object should be active during keyboard press of Ctrl+V.

    Other thing is (if it is easier) just create Paste button and put the code to its Click method. 

    Otherwise send me the cut version of your solution and i'll try to find a solution for you.

    cheers

     

    Friday, September 19, 2008 5:23 AM
  •  

    Hi Dilsh,

     Thanks for your  help. I tried the code with the UserControl's ParentForm.KeyUP method and it works Smile .But I ha ve small problem here. It some times doesnt work on the First time (Ctrl+V) pressed, later in the second attempt it work. Can you suggest me how to make the object (Datagridview in the user control) active.

     

    Because i feel that once i click on the gridview , it should be active. Sad

    Wednesday, October 1, 2008 6:28 AM
  •  Biju557566 wrote:

     

    Hi Dilsh,

     Thanks for your  help. I tried the code with the UserControl's ParentForm.KeyUP method and it works .But I ha ve small problem here. It some times doesnt work on the First time (Ctrl+V) pressed, later in the second attempt it work. Can you suggest me how to make the object (Datagridview in the user control) active.

    Because i feel that once i click on the gridview , it should be active.

     

    Hi,

    If you are using ParentForm.KeyUP method, it should not matter which object is currently active (normally).

    1) As I said, to be on the safe side create a button "Paste" and run the paste code on its click.

    2) Move the code to a separate function and run the function on several object's KeyUp methods. (very ugly workaround though)

    Sunday, October 5, 2008 5:24 PM
  • Hi Dil

    Is it possible to apply this to Gridview WEB control?

     

    Thanks

     

    SS

    Friday, November 14, 2008 10:56 AM
  • HI Dil,

             Can you please let me know how can i proceed with the same code in the web application or please let us know if this can be implemented in the web applications or not.

     

    thanks

    vamsi
    Thursday, June 24, 2010 1:42 PM
  • Thank you for this it was very helpfull

    here is my c++ .net version based on your code

    private: System::Void dataGridView1_KeyUp(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
    			 if(e->Control && e->KeyCode == System::Windows::Forms::Keys::C){
    				 Clipboard::SetDataObject(this->dataGridView1->GetClipboardContent());
    			 }
    			 else if(e->Control && e->KeyCode == System::Windows::Forms::Keys::V){
    				 System::Windows::Forms::IDataObject^ dataInclipboard= System::Windows::Forms::Clipboard::GetDataObject();
    				 String^ stringInclipboard = (System::String ^)dataInclipboard->GetData(DataFormats::UnicodeText);
    				 int startcolumn = this->dataGridView1->SelectedCells[0]->ColumnIndex;
    				 int startrow = this->dataGridView1->SelectedCells[0]->RowIndex;
    				 array<wchar_t>^ separator = {'\r', '\n'};
    				 array<wchar_t>^ columnsplitter = {'\t'};
    				 array <String^>^ rowsInclipboard = stringInclipboard->Split(separator,StringSplitOptions::RemoveEmptyEntries);
    				 for(int i=0;i<rowsInclipboard->Length;i++){
    						 if(this->dataGridView1->RowCount-1>=startrow+i){
    						 array <String^>^ cellsInrow = rowsInclipboard[i]->Split(columnsplitter);
    						 for(int j=0;j<cellsInrow->Length;j++){
    							 if(this->dataGridView1->ColumnCount-1>=startcolumn+j)
    								 this->dataGridView1->Rows[startrow+i]->Cells[startcolumn+j]->Value = cellsInrow[j];
    						 }
    					 }
    
    				 }
    			 }
    			 
    		 }

    Tuesday, July 6, 2010 5:47 PM
  • Hello All,

         Can you please specify the code to get the copy paste working in the web applications. The aspect that you have mentioned is for the windows applications so can you please provide me the code to implement the same copy paste functionality in the web applications .

     

    regards,

    vamsi.

    Tuesday, July 13, 2010 8:27 AM
  • Hello Sir,

       I need to be able to access the clipboard data using javascript . I have completed implementing this in internet explorer but haivng an issue implemnting this feature in mozilla .

    code in internet explorer:

       document.getElementById('ClipboardContent').value = window.clipboardData.getData('Text');

     

     

     

    Regards,

    vamsi.

    Tuesday, July 13, 2010 12:47 PM
  • I finally got this code working in VB .net! Here's my code: (make sure to put it inside the right event)

     'if user clicked Shift+Ins or Ctrl+V (paste from clipboard)
            If ((e.Shift And e.KeyCode = Keys.Insert) Or (e.Control And e.KeyCode = Keys.V)) Then
    
                Dim rowSplitter() As Char = {vbCr, vbLf}
                Dim columnSplitter() As Char = {vbTab}
                'get the text from clipboard
                Dim dataInClipboard As IDataObject = Clipboard.GetDataObject()
                Dim stringInClipboard As String = CType(dataInClipboard.GetData(DataFormats.Text), String)
                'split it into lines
                Dim rowsInClipboard As String() = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries)
    
                'rowsInClipboard = {"AxB", "CxD"}
    
                'get the row and column of selected cell in grid
                Dim r As Integer = dgvDataEntry.SelectedCells(0).RowIndex
                Dim c As Integer = dgvDataEntry.SelectedCells(0).ColumnIndex
                'add rows into grid to fit clipboard lines
                If (dgvDataEntry.Rows.Count < (r + rowsInClipboard.Length)) Then
                    dgvDataEntry.Rows.Add(r + rowsInClipboard.Length - dgvDataEntry.Rows.Count)
                End If
                ' loop through the lines, split them into cells and place the values in the corresponding cell.
                For index = 0 To rowsInClipboard.Length - 1
                    'split row into cell values
                    Dim valuesInRow As String() = rowsInClipboard(index).Split(columnSplitter)
                    'cycle through cell values
                    For j = 0 To valuesInRow.Length - 1
                        'assign cell value, only if it within columns of the grid
                        If (dgvDataEntry.ColumnCount - 1 >= c + j) Then
                            dgvDataEntry.Rows(r + index).Cells(c + j).Value = valuesInRow(j)
                        End If
                    Next
                Next
    
    
            End If

    The hardest part was trying to use \r and \n but I realized to use VB constants instead. Thanks for the original code in c#! Helped me a lot today.

    Thursday, August 22, 2013 1:29 PM
  • Hello,

    The following does not include the key combo sequence as that has already been covered.

    What this does is attempts to determine if we have the proper format then add the data from Excel to a DataTable then to a DataGridView via the DataTable.

    Public Class Form1
        Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click
            DataGridView1.DataSource = Nothing
            Try
                Dim ClipboardData As IDataObject = Clipboard.GetDataObject()
                If Not ClipboardData Is Nothing Then
                    'Next proceed only of the copied data is in the CSV format indicating Excel content
                    If (ClipboardData.GetDataPresent(DataFormats.CommaSeparatedValue)) Then
                        'Cast the copied data in the CommaSeparatedValue format & hold in a StreamReader Object
                        Dim ClipboardStream As New IO.StreamReader(CType(ClipboardData.GetData(DataFormats.CommaSeparatedValue), IO.Stream))
                        Dim FormattedData As String = ""
                        'Define a DataTable to hold the copied data for binding to the DataGrid
                        Dim Table As New DataTable With {.TableName = "ExcelData"}
                        Console.WriteLine("Here is what we got")
                        While (ClipboardStream.Peek() > 0)
                            Dim SingleRowData As Array
                            'Multipurpose Loop Counter
                            Dim LoopCounter As Integer = 0
                            'Read a line of data from the StreamReader object
                            FormattedData = ClipboardStream.ReadLine()
                            Console.WriteLine(FormattedData)
                            SingleRowData = FormattedData.Split(",".ToCharArray)
                            If Table.Columns.Count <= 0 Then
                                For LoopCounter = 0 To SingleRowData.GetUpperBound(0)
                                    Table.Columns.Add()
                                Next
                                LoopCounter = 0
                            End If
                            Dim rowNew As DataRow
                            rowNew = Table.NewRow()
                            For LoopCounter = 0 To SingleRowData.GetUpperBound(0)
                                rowNew(LoopCounter) = SingleRowData.GetValue(LoopCounter)
                            Next
                            LoopCounter = 0
                            Table.Rows.Add(rowNew)
                            rowNew = Nothing
                        End While
                        ClipboardStream.Close()
                        DataGridView1.DataSource = Table
                    Else
                        MessageBox.Show("Clipboard data does not seem to be copied from Excel!")
                    End If
                Else
                    MessageBox.Show("Clipboard is empty!")
                End If
            Catch exp As Exception
                MessageBox.Show(exp.Message)
            End Try
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Thursday, August 22, 2013 8:28 PM
    Moderator
  • Thanks Dil, you have just made my life easier!
    Thursday, January 21, 2016 7:52 PM
  • Thanks a lot Dil!

    i've created the button Paste and copied your code in the even and it works as expected!

    quite a few years passed after you posted the solution, but it is still helping people.

    Thursday, June 23, 2016 12:53 PM
  • This code is working for me but I have a doubt if that particular cell also contains comma that time it's causing problem.
    Wednesday, October 4, 2017 8:08 AM
  • Works great! Thank you :)
    Tuesday, January 30, 2018 6:27 PM
  • I'm using this solution 12 years after it was posted and it still works. It's also fast and efficient. Just brilliant. Thanks!
    Thursday, March 15, 2018 10:07 AM