C# 完美實現DataGridView批量複製多行/單元格資料並貼上功能
阿新 • • 發佈:2018-11-24
C#系統預設情況下不支援批量貼上多行或多個單元格資料,但是有時想直接複製dataGridView的一部分資料,然後一起貼上到DatagridView的指定位置。
關鍵步驟
0.建立一個C#窗體應用程式this,呼叫一個DataGridView控制元件this.dataGridView1
1.重寫this.dataGridView1的ProcessCmdKey方法,獲取鍵盤點選事件,識別Ctrl+V
2.獲取剪貼簿HTML資料並解析,將多行多列資料分別填至游標指定或選中的單元格中
3.清空訊息引數,防止系統呼叫預設的剪貼功能,將複製的第一行資料不正確地填充至一個單元格中
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //在檢測到按Ctrl+V鍵後,系統無法複製多單元格資料,重寫ProcessCmdKey方法,遮蔽系統貼上事件,使用自定義貼上事件,在事件中對剪貼簿的HTML格式進行處理,獲取表資料,更新DataGrid控制元件內容 if (keyData == (Keys.V| Keys.Control)) // && { IDataObject idataObject = Clipboard.GetDataObject(); string[] s = idataObject.GetFormats(); string data; if (!s.Any(f=>f=="OEMText")) { if (!s.Any(f=>f=="HTML Format")) { } else { data = idataObject.GetData("HTML Format").ToString();//多個單元格 copyClipboardHtmltoGrid(data); //msg = Message.; msg = new Message(); return base.ProcessCmdKey(ref msg, Keys.Control); } }else data = idataObject.GetData("OEMText").ToString();//單個單元格,使用系統功能,無需處理 } return base.ProcessCmdKey(ref msg, keyData); }
當複製單行資料時,剪貼簿中沒有HTML格式的資料,此時可獲取OEMText格式的資料,或者不加處理,使用系統貼上功能;
當複製多行時,可以通過解析剪貼簿的HTML格式的資料,獲取多個單元格的資料
關於Windows剪貼簿資料格式的問題,可以參考我的上一篇部落格
copyClipboardHtmltoGrid(data);方法識別剪貼簿的HTML格式資料,並將結果動態地賦值給this.dataGridView1
private void copyClipboardHtmltoGrid(string data) { //截取出HTML內容 int start, end = -1, index, rowStart = 0, columnStart = 0; Regex regex = new Regex(@"StartFragment:\d+"); Match match = regex.Match(data); if (match.Success) { start = Convert.ToInt16(match.Value.Substring(14)); } else { return; } regex = new Regex(@"EndFragment:\d+"); match = regex.Match(data, match.Index + match.Length); if (match.Success) { end = Convert.ToInt16(match.Value.Substring(12)); } else { return; } if (this.dataGridView1.SelectedCells.Count > 0) { rowStart = this.dataGridView1.SelectedCells[0].RowIndex; columnStart = this.dataGridView1.SelectedCells[0].ColumnIndex; } data = data.Substring(start, end - start); MatchCollection matchcollection = new Regex(@"<TR>[\S\s]*?</TR>").Matches(data), sub_matchcollection; int count = rowStart + matchcollection.Count - this.dataGridView1.RowCount; if (count>=0) { this.dataGridView1.Rows.Add(count+1); } for (int i = 0; i < matchcollection.Count && i + rowStart < this.dataGridView1.RowCount ; i++) { sub_matchcollection = new Regex(@"<TD>[\S\s]*?</TD>").Matches(matchcollection[i].Value); for (int j = 0; j < sub_matchcollection.Count && j + columnStart < this.dataGridView1.ColumnCount; j++) { this.dataGridView1.Rows[i + rowStart].Cells[j + columnStart].Value = sub_matchcollection[j].Value.Substring(4, sub_matchcollection[j].Length - 9).Trim(); } } }
效果截圖: