DataGridView:将完成复制到剪贴板

时间:2012-05-09 17:32:04

标签: c# .net winforms visual-studio-2010 datagridview

我在.Net应用程序中有一个DataGridView(V4 C#VS2010)&想要通过点击按钮将所有数据复制到剪贴板。没问题 -

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

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

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

var mySelectedCells = dataGridView1.SelectedCells;

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

5 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:1)

以下是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;
        }
    }

答案 2 :(得分:0)

我认为以下方法将完全按照您的意愿行事。只需在按钮单击事件中使用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

答案 3 :(得分:0)

DataGridView列可以是可见/不可见的,也可以按照创建顺序不同的顺序显示。这段代码兼顾了两者:

            JSONObject jsonObject = new JSONObject();
            jsonObject.accumulate("name", name);
            String json = jsonObject.toString();

            URL url = new URL("http://website_link");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

            OutputStream os = urlConnection.getOutputStream();
            os.write(json.getBytes("UTF-8"));
            os.close();

            InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8")), 8);
            String line;
            json = "";

            while ((line = reader.readLine()) != null) {
                json += line;
            }

            inputStream.close();

            jsonObject = new JSONObject(json);

            inputStream.close();
            urlConnection.disconnect();

            ...

答案 4 :(得分:0)

您应该更改DataGridView的multiselect属性。这是代码:

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