DataGridView: Copy complete to clipboard
Here is a version of the VB code in C# with options to copy headers and to only copy selected rows.
private void CopyDataGridViewToClipboard(DataGridView dgv, bool includeHeaders = true, bool allRows = false)
{
// copies the contents of selected/all rows in a data grid view control to clipboard with optional headers
try
{
string s = "";
DataGridViewColumn oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
if (includeHeaders)
{
do
{
s = s + oCurrentCol.HeaderText + "\t";
oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
while (oCurrentCol != null);
s = s.Substring(0, s.Length - 1);
s = s + Environment.NewLine; //Get rows
}
foreach (DataGridViewRow row in dgv.Rows)
{
oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
if (row.Selected || allRows)
{
do
{
if (row.Cells[oCurrentCol.Index].Value != null) s = s + row.Cells[oCurrentCol.Index].Value.ToString();
s = s + "\t";
oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
while (oCurrentCol != null);
s = s.Substring(0, s.Length - 1);
s = s + Environment.NewLine;
}
}
Clipboard.SetText(s);
}
catch (Exception ex)
{
toolStripStatusLabel2.Text = @"Error: " + ex.Message;
}
}
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());
You should change multiselect property of DataGridView. Here is the code:
private void copyToClipboard()
{
dataGridView1.MultiSelect = True;
dataGridView1.SelectAll();
DataObject dataObj = dataGridView1.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}