クリップボードへのコピーはDataGridViewの機能として提供されており、既定で有効となっています。そしてその処理は、DataGridView.GetClipboardContent()を用いてプログラムから実行することも可能です。DataGridView.GetClipboardContent Method (System.Windows.Forms) | Microsoft Learn
DataObject data = dataGridView.GetClipboardContent(); if (data != null) // 選択されているセルがないと、nullが返される { Clipboard.SetDataObject(data); }
クリップボードへコピーするときの内容を変更するには、 DataGridViewCellを継承するクラスを定義し、GetClipboardContent()をオーバーライドします。なおヘッダーを含めるかどうかを変更するだけならば、ClipboardCopyModeを設定します。
public class CustomDataGridViewTextBoxCell : DataGridViewTextBoxCell { protected override object GetClipboardContent(int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) { bool csv = String.Equals(format, DataFormats.CommaSeparatedValue, StringComparison.OrdinalIgnoreCase); if (csv || String.Equals(format, DataFormats.Text, StringComparison.OrdinalIgnoreCase) || String.Equals(format, DataFormats.UnicodeText, StringComparison.OrdinalIgnoreCase)) { StringBuilder sb = new StringBuilder(64); string formattedValue = GetEditedFormattedValue(rowIndex, DataGridViewDataErrorContexts.Formatting | DataGridViewDataErrorContexts.ClipboardContent) as string; if (formattedValue != null) { if (csv) { if (formattedValue.IndexOf('"') != -1) { // 二重引用符を含むならば、二重引用符でエスケープし二重引用符で囲む sb.AppendFormat("\"{0}\"", formattedValue.Replace("\"", "\"\"")); } else if (formattedValue.IndexOf(',') != -1 || formattedValue.IndexOf("\r\n") != -1) { // カンマか改行を含むならば、二重引用符で囲む sb.AppendFormat("\"{0}\"", formattedValue); } else { sb.Append(formattedValue); } } else { sb.Append(formattedValue); } } if (!lastCell) { // 最後の列でなければ、区切り文字を追加 sb.Append(csv ? ',' : '\t'); } else if (!inLastRow) { // 最後の列だが最後の行でなければ、改行文字を追加 sb.Append("\r\n"); } return sb.ToString(); } return null; } }GetClipboardContent - DataGridViewCell.cs
そしてDataGridViewColumnを継承するクラスを定義し、そのコンストラクタでDataGridViewCellを継承したクラスのインスタンスを渡します。
public class CustomDataGridViewColumn : DataGridViewColumn { public CustomDataGridViewColumn() : base(new CustomDataGridViewTextBoxCell()) { SortMode = DataGridViewColumnSortMode.Automatic; } public override DataGridViewCell CellTemplate { get { return base.CellTemplate; } set { if (value != null && !(value is CustomDataGridViewTextBoxCell)) { throw new InvalidCastException(); } base.CellTemplate = value; } } }DataGridViewTextBoxColumn.cs
これを利用するときは、DataGridViewColumnを継承したクラスを作成し、それを列に追加します。
DataGridViewColumn column = new CustomDataGridViewColumn(); column.Name = ""; column.HeaderText = ""; dataGridView.Columns.Add(column);
もしくは定義したDataGridViewCellを継承するクラスをテンプレートとして、DataGridViewColumnを作成します。
DataGridViewColumn column = new DataGridViewColumn(new CustomDataGridViewTextBoxCell());
HTML形式では、GetClipboardContent()から
protected override object GetClipboardContent(int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) { if (String.Equals(format, DataFormats.Html, StringComparison.OrdinalIgnoreCase)) { return "SAMPLE"; } return null; }
のように返すと、クリップボードには
Version:1.0 StartHTML:00000097 EndHTML:00000177 StartFragment:00000133 EndFragment:00000141 <HTML> <BODY> <!--StartFragment-->SAMPLE <!--EndFragment--> </BODY> </HTML>
のように格納されるため、body要素内に記述したい内容だけを返すようにします。GetClipboardContentForHtml - DataGridViewMethods.cs
「追加情報:FORMATETC 構造体が無効です (HRESULT からの例外:0x80040064 (DV_E_FORMATETC))」
c# - Cryptic exception copy/pasting from DataGridView into Excel 2002 - Stack OverflowクリップボードからセルへのコピーはDataGridViewの機能として提供されていないため、自力で実装する必要があります。
IDataObject iData = Clipboard.GetDataObject(); string text; char delimiter; if (iData.GetDataPresent(DataFormats.CommaSeparatedValue)) // CSV形式の場合 { object obj = iData.GetData(DataFormats.CommaSeparatedValue); if (obj is MemoryStream) { MemoryStream memoryStream = (MemoryStream)obj; StreamReader streamReader = new StreamReader(memoryStream, Encoding.Default); // ExcelからCSV形式でデータを取得するときには文字化けすることがあるため、文字エンコーディングを明示する // c# - Get CSV Data from Clipboard (pasted from Excel) that contains accented characters - Stack Overflow text = streamReader.ReadToEnd(); } else { text = (string)obj; } delimiter = ','; } else if (iData.GetDataPresent(typeof(string))) // テキスト形式の場合 { text = (string)iData.GetData(typeof(string)); delimiter = '\t'; } else // その他の場合 { return; } // 改行文字で行ごとに分割する string[] lines = text.Split(new string[] { "\n", "\r\n", "\r" }, StringSplitOptions.None); // 区切り文字で要素ごとに分割する List<string[]> elements = new List<string[]>(); foreach (string line in lines) { elements.Add(line.Split(delimiter)); } // ※CSV形式ではフィールドに改行や区切り文字が含まれていると、不適切に分割される // 選択されている最初のセルを基準として、セルに値を設定する DataGridViewSelectedCellCollection selectedCells = dataGridView.SelectedCells; int columnIndex = selectedCells[0].ColumnIndex; int rowIndex = selectedCells[0].RowIndex; for (int y = 0; y < elements.Count; y++) { for (int x = 0; x < elements[y].Length; x++) { dataGridView[columnIndex + x, rowIndex + y].Value = elements[y][x]; } }