Search code examples
vb.netdatagridviewcopy-paste

Copy/Paste within DataGridView


I am trying to make copy and pasting within a DataGridView to act similarly to Excel. My current code performs this with the exception of the first cell, which seems to be pasting all contents from the clipboard into the first cell. Below is the code I am using on the cell_keydown event.

Just to clarify, if I copy the following:

Copied Data

I get the result:

Pasted Data

The pasted data, does have a space between the two dates prior to clicking off the cell.

If anyone has a better way to accomplish what I am ultimately trying to do that would be appreciated as well!

If e.Control AndAlso e.KeyCode = Keys.C Then
    Dim d As DataObject = dgv1.GetClipboardContent()
    Clipboard.SetDataObject(d)
    e.Handled = True

ElseIf e.Control AndAlso e.KeyCode = Keys.V Then
    Dim s As String = Clipboard.GetText().Replace(vbCr, " ")
    Dim lines As String() = s.Trim.Split(vbLf)
    Dim row As Integer = dgv1.CurrentCell.RowIndex
    Dim col As Integer = dgv1.CurrentCell.ColumnIndex
    Dim linesCount As Integer = lines.Count()

    If (row + linesCount) - dgv1.RowCount > 0 Then dgv1.Rows.Add((row + linesCount) - dgv1.RowCount)

    For Each line As String In lines
        If line.Length > 0 Then
            Dim cells As String() = line.Split(vbTab)
            For i As Integer = 0 To cells.GetLength(0) - 1
                dgv1.CurrentCell.Value = cells(i)
                If col + i < dgv1.ColumnCount Then
                    dgv1(col + i, row).Value = cells(i)
                Else
                    Exit For
                End If
            Next
            row += 1
        Else
            Exit For
        End If
    Next
End If

Solution

  • Better to create methods for the copy/paste routines so you can call them from different places in your code, like on button click, on key press, on menu item click ...etc.

    I don't think you have a problem with the Copy part since the GetClipboardContent function will do the job. As for the Paste part, the following code snippet gets the data from the Clipboard and pastes the values of a selection range of cells starting from the CurrentCell. The out of range cells are trimmed.

    Private Sub CopyCells()
        Clipboard.SetDataObject(DataGridView1.GetClipboardContent)
    End Sub
    
    Private Sub PasteCells()
        Dim s = Clipboard.GetText
        Dim ci = DataGridView1.CurrentCell.ColumnIndex
        Dim ri = DataGridView1.CurrentCell.RowIndex
        Dim colCount = DataGridView1.Columns.Count
        Dim rowCount = DataGridView1.Rows.Count
    
        For Each r In s.Split({ControlChars.CrLf}, StringSplitOptions.None)
            Dim Cell = ci
            For Each c In r.Split({ControlChars.Tab}, StringSplitOptions.None)
                If Cell >= colCount Then Exit For
                DataGridView1(Cell, ri).Value = c
                Cell += 1
            Next
            ri += 1
            If ri >= rowCount Then Exit For
        Next
    End Sub
    

    Call them from the DGV.KeyDown event for example as follows:

    Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyDown
        If e.Control Then
            Select Case e.KeyCode
                Case Keys.C
                    CopyCells()
                    e.Handled = True
                Case Keys.V
                    PasteCells()
                    e.Handled = True
            End Select
        End If
    End Sub