DataGridView:将完成复制到剪贴板

我在.Net应用程序(V4 C#VS2010)中有一个DataGridView,并希望通过单击按钮将所有数据复制到剪贴板。 没问题 –

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

问题是用户可能已经在DataGrid上选择了一些单元格,行等,我真的不想更改该选择。 以上显然选择了一切。 我可以dataGridView1.ClearSelection(); 在最后,稍微好一点,但仍然没有达到要求。

我可以保存选定的单元格:

 var mySelectedCells = dataGridView1.SelectedCells; 

但是如何在复制后在DataGrid上重新选择那些选定的单元? 有没有一种简单的方法可以将选定的单元格集合重新放回DataGrid? 也许有一种更好的方法可以将整个网格首先复制到剪贴板而不影响当前选定的单元格?

我想如果您只想将单元格的内容表示为文本并将它们复制到剪贴板(制表符分隔),您可以执行以下操作:

  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); 

输出看起来与GetClipboardContent()的输出非常相似,但要注意任何DataGridViewImageColumns或任何非隐式字符串的类型。

编辑: Anthony是正确的,使用StringBuilder避免为每个连接分配一个新字符串。 新代码:

  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()); 

以下是C#中VB代码的一个版本,其中包含复制标题和仅复制选定行的选项。

  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; } } 

我认为下面的方法将完全按照你的意愿行事。 只需在按钮单击事件中使用DataGridView名称调用此方法即可。

 Private Sub CopyDataGridViewToClipboard(ByRef dgv As DataGridView) Try Dim s As String = "" Dim oCurrentCol As DataGridViewColumn 'Get header oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible) Do s &= oCurrentCol.HeaderText & Chr(Keys.Tab) oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, _ DataGridViewElementStates.Visible, DataGridViewElementStates.None) Loop Until oCurrentCol Is Nothing s = s.Substring(0, s.Length - 1) s &= Environment.NewLine 'Get rows For Each row As DataGridViewRow In dgv.Rows oCurrentCol = dgv.Columns.GetFirstColumn(DataGridViewElementStates.Visible) Do If row.Cells(oCurrentCol.Index).Value IsNot Nothing Then s &= row.Cells(oCurrentCol.Index).Value.ToString End If s &= Chr(Keys.Tab) oCurrentCol = dgv.Columns.GetNextColumn(oCurrentCol, _ DataGridViewElementStates.Visible, DataGridViewElementStates.None) Loop Until oCurrentCol Is Nothing s = s.Substring(0, s.Length - 1) s &= Environment.NewLine Next 'Put to clipboard Dim o As New DataObject o.SetText(s) Clipboard.SetDataObject(o, True) Catch ex As Exception ShowError(ex, Me) End Try End Sub