Copy+Paste DataGridViewSelectedCellCollection to/from Clipboard
Assume that I have a DataGridView
which is populated by a number of different strings
(different length, numbers and plain text) in Cells.
Want I want to do is to copy and paste these strings, which could be any selection of Cells.
My approach to copy is:
if (e.Control && e.KeyCode == Keys.C)
{
// copy
DataGridViewSelectedCellCollection tmpCells = this.MyDataGridView.SelectedCells;
Clipboard.SetDataObject(tmpCells);
}
Which is working properly.
My approach to paste is:
if (e.Control && e.KeyCode == Keys.V)
{
// paste
IDataObject dataInClipboard = Clipboard.GetDataObject();
string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);
char[] rowSplitter = { 'r', 'n' };
char[] columnSplitter = { 't' };
string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);
int r1 = this.MyDataGridView.SelectedCells[0].RowIndex;
int c1 = this.MyDataGridView.SelectedCells[0].ColumnIndex;
int r2 = this.MyDataGridView.SelectedCells[this.MyDataGridView.SelectedCells.Count-1].RowIndex;
int c2 = this.MyDataGridView.SelectedCells[this.MyDataGridView.SelectedCells.Count-1].ColumnIndex;
int r = Math.Min(r1, r2); // Do not care if selection was taken by drag mouse up or down, always start from min
int c = Math.Min(c1, c2); // Do not care if selection was taken by drag mouse left or right, always start from min
for (int iRow = 0; iRow < rowsInClipboard.Length; ++iRow )
{
string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);
for (int iCol = 0; iCol < valuesInRow.Length; ++iCol )
{
if (this.MyDataGridView.ColumnCount-1 >= c + iCol)
{
DataGridViewCell DGVC = (this.MyDataGridView.Rows[r + iRow].Cells[c + iCol]);
DGVC.Value = valuesInRow[iCol];
}
}
}
}
}
Which works fine UNLESS the string itself DOES NOT contain any delimiter I specified with rowSplitter
and columnSplitter
. But this unfortunately is the case very often. It then separates the string and expands it to the next cell.
Example:
Cell[n] = {"This string contains a new line delimiter n but should use only one cell."}
Will be pasted to:
Cell[n] = {"This string contains a new line delimiter"};
Cell[n+1] = {"but should use only one cell."}
So my question is: is it possible to restore the DataGridViewSelectedCellCollection
as it was copied to the clipboard before? Just casting from object
to DataGridViewSelectedCellCollection
will not work:
DataGridViewSelectedCellCollection DGSCC = (DataGridViewSelectedCellCollection)dataInClipboard; // compiles, but throws exception at runtime
Do I have any other option but parsing each string by a defined formatting?
You will have to define own format for clipboard, which will do what default one can't do for you.
Simplest solution in this specific case is to convert multi-line breaks into n
and then convert back when you paste, but in any case it means no more
DataGridViewSelectedCellCollection tmpCells = this.MyDataGridView.SelectedCells;
Clipboard.SetDataObject(tmpCells);
but
DataGridViewSelectedCellCollection tmpCells = this.MyDataGridView.SelectedCells;
string result = "";
foreach(DataGridViewCell cell in tempCells)
// ... try to replicate what default clipboard text representation does
// change line breaks
Clipboard.SetDataObject(result.Replace("xdxa", "n"));
and paste will be:
IDataObject dataInClipboard = Clipboard.GetDataObject();
string stringInClipboard = dataInClipboard.GetData(DataFormats.Text).ToString().Replace("n", "xdxa");
链接地址: http://www.djcxy.com/p/62264.html
上一篇: 将多个Excel单元复制到一个中