14

.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に戻す簡単な方法はありますか?おそらく、現在選択されているセルに影響を与えることなく、グリッド全体を最初にクリップボードにコピーするためのより良い方法がありますか?

4

5 に答える 5

14

セルの内容をテキストとして表現し、タブ区切りでクリップボードにコピーしたい場合は、次のようにすることができます。

    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());
于 2012-05-09T23:44:42.340 に答える
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;
        }
    }
于 2017-02-07T00:33:50.707 に答える
1

DataGridViewのmultiselectプロパティを変更する必要があります。コードは次のとおりです。

private void copyToClipboard()
{
  dataGridView1.MultiSelect = True;
  dataGridView1.SelectAll();
  DataObject dataObj = dataGridView1.GetClipboardContent();
  if (dataObj != null)
  Clipboard.SetDataObject(dataObj);
}
于 2019-08-13T06:54:19.510 に答える
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
于 2014-12-24T08:05:09.947 に答える
0

DataGridView列は、表示/非表示にすることができ、作成された順序とは異なる順序で表示することもできます。このコードは両方を処理します。

public static void CopyGridViewToClipboard(DataGridView gvCopy)
    {
        if (gvCopy == null) return;
        StringBuilder s = new StringBuilder();

        int offset = gvCopy.ColumnHeadersVisible ? 1 : 0;
        int visibleColumnsCount = 0;

        //count visible columns and build mapping between each column and it's display position
        Dictionary<int, int> indexMapping = new Dictionary<int, int>();
        int currIndex = 0;
        int lastFoundMinDisplayIndex = -1;
        for (int j = 0; j < gvCopy.ColumnCount; j++)
        {
            //find min DisplayIndex >= currIndex where column is visible
            int minDisplayIndex = 100000;
            int minDisplayIndexColumn = 100000;
            for (int k = 0; k < gvCopy.ColumnCount; k++)
            {
                if ((gvCopy.Columns[k].Visible) && (gvCopy.Columns[k].DisplayIndex >= currIndex) && (gvCopy.Columns[k].DisplayIndex > lastFoundMinDisplayIndex))
                {
                    if (gvCopy.Columns[k].DisplayIndex < minDisplayIndex)
                    {
                        minDisplayIndex = gvCopy.Columns[k].DisplayIndex;
                        minDisplayIndexColumn = k;
                    }
                }
            }

            if (minDisplayIndex == 100000) break;

            indexMapping.Add(minDisplayIndexColumn, currIndex);

            lastFoundMinDisplayIndex = minDisplayIndex;
            currIndex++;
        }
        visibleColumnsCount = currIndex;

        //put data in temp array -- required to position columns in display order
        string[,] data = new string[gvCopy.RowCount + offset, visibleColumnsCount];

        if (gvCopy.ColumnHeadersVisible)
        {
            for (int j = 0; j < gvCopy.ColumnCount; j++)
            {
                if (gvCopy.Columns[j].Visible)
                {
                    data[0, indexMapping[j]] = gvCopy.Columns[j].HeaderText;
                }
            }
        }

        for (int i = 0; i < gvCopy.RowCount; i++)
        {
            for (int j = 0; j < gvCopy.ColumnCount; j++)
            {
                if (gvCopy.Columns[j].Visible)
                {
                    data[i + offset, indexMapping[j]] = gvCopy[j, i].FormattedValue.ToString();
                }
            }
        }

        //copy data
        for (int i = 0; i < gvCopy.RowCount + offset; i++)
        {
            for (int j = 0; j < visibleColumnsCount; j++)
            {
                s.Append(data[i, j]);

                s.Append("\t");
            }
            s.Append("\r\n");
        }
        Clipboard.SetDataObject(s.ToString());
    }
于 2019-03-27T21:20:14.037 に答える