C# – DataGridView: Copy complete to clipboard

cdatagridviewnetvisual studio 2010winforms

I have a DataGridView in a .Net application (V4 C# VS2010) & want to copy all the data to the clipboard on the click of a button. No problem –

private void copyToClipboard()
{
    dataGridView1.SelectAll();
    DataObject dataObj = dataGridView1.GetClipboardContent();
    if (dataObj != null)
        Clipboard.SetDataObject(dataObj);
}

Problem is that the user might already have some cells, rows etc selected on the DataGrid & I don't really want to change that selection. The above obviously selects everything. I could dataGridView1.ClearSelection(); at the end which is marginally better but still doesn't achieve what's required.

I can save the selected cells:

var mySelectedCells = dataGridView1.SelectedCells;

but how do I get those selected cells reselected on the DataGrid after the copy? Is there an easy way to get the selected cells collection back into the DataGrid? Perhaps there is a better way to get the whole grid copied to the clipboard in the first place without affecting presently selected cells?

Best Answer

I suppose if you just wanted to represent the contents of the cells as text and copy them to the clipboard, tab-delimited, you could do something like:

    var newline = System.Environment.NewLine;
    var tab = "\t";
    var clipboard_string = "";

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
         for (int i=0; i < row.Cells.Count; i++)
         {
              if(i == (row.Cells.Count - 1))
                   clipboard_string += row.Cells[i].Value + newline;
              else
                   clipboard_string += row.Cells[i].Value + tab;
         }
    }

    Clipboard.SetText(clipboard_string);

The output seems pretty similar to that of the GetClipboardContent(), but be careful for any DataGridViewImageColumns or any type that isn't implicitly a string.

Edit: Anthony is correct, use StringBuilder to avoid allocating a new string for every concatenation. The new code:

    var newline = System.Environment.NewLine;
    var tab = "\t";
    var clipboard_string = new StringBuilder();

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        for (int i = 0; i < row.Cells.Count; i++)
        {
            if (i == (row.Cells.Count - 1))
                clipboard_string.Append(row.Cells[i].Value + newline);
            else
                clipboard_string.Append(row.Cells[i].Value + tab);
        }
    }

    Clipboard.SetText(clipboard_string.ToString());
Related Topic