- В свойствах формы прописать свойство keypreview равным true
- В KeyUp добавить следующий обработчик событий:
private void form1_KeyUp(object sender, KeyEventArgs e)
{
//if user clicked Shift+Ins or Ctrl+V (paste from clipboard)
if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))
{
char[] rowSplitter = { '\r', '\n' };
char[] columnSplitter = { '\t' };
//get the text from clipboard
IDataObject dataInClipboard = Clipboard.GetDataObject();
string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);
//split it into lines
string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);
//get the row and column of selected cell in grid
int r = grid.SelectedCells[0].RowIndex;
int c = grid.SelectedCells[0].ColumnIndex;
//add rows into grid to fit clipboard lines
if (grid.Rows.Count < (r + rowsInClipboard.Length))
grid.Rows.Add(r + rowsInClipboard.Length - grid.Rows.Count);
// loop through the lines, split them into cells and place the values in the corresponding cell.
for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)
{
//split row into cell values
string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);
//cycle through cell values
for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
{
//assign cell value, only if it within columns of the grid
if (grid.ColumnCount - 1 >= c + iCol)
grid.Rows[r + iRow].Cells[c + iCol].Value = valuesInRow[iCol];
}
}
}
}
Обращаю внимание, что valuesInRow[iCol] необходимо привести к нужному типу данных, а то потом будут проблемы.
P.S.: Оригинал можно почитать здесь
Добрый день!
ОтветитьУдалитьСпасибо за простое и красивое решение.
Есть пара дополнений:
1. На форме может быть несколько DataGridView - а Вы в коде задали жестко один конкретный. Вот вариант реализации поиска DataGridView, который вызвал событие (поместить в самом начале функции):
//Find the source of the event
Form form = (Form)sender;
DataGridView grid = null;
for (int i = 0; i < form.Controls.Count; i++)
{
if (form.Controls[i].ContainsFocus)
{
if (form.Controls[i].GetType().ToString() != "System.Windows.Forms.DataGridView")
return;
grid = (DataGridView)form.Controls[i];
break;
}
}
2. Если вы вошли в режим редактирования в одной из ячеек DataGridView и там выполнили Ctrl-V, то нужно обновить данную ячейку, иначе там мусор. В самый конец Вашей функции добавить строчку:
grid.RefreshEdit(); //Refresh the edited cell
Еще раз спасибо!
И вам спасибо :)
ОтветитьУдалитьА как быть с много строчной вставкой?
ОтветитьУдалитьмне надо было только два столбца дополнять, но под универсальный случай допилить не проблематично
Удалитьprivate void pasteClipboardtoDG()
{
if (Clipboard.ContainsText(TextDataFormat.Text))//сли в Clipboard есть текст копируем его в лист
{
string[] tabvalfld = Clipboard.GetText().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); //Regex.Split(string,"xx")
int i = 0;
foreach (var s in tabvalfld)
{
string[] tabvalfld1 = s.Split('\t');
if (tabvalfld1[0] != null)
{
dataGridView1.Rows.Add(1);
dataGridView1.Rows[i].Cells[0].Value = tabvalfld1[0];
if (tabvalfld1.Length > 1 && tabvalfld1[1] != null)
{
dataGridView1.Rows[i].Cells[1].Value = tabvalfld1[1];
}
i++;
}
}
}
else
{
MessageBox.Show("No data in Clipboard", "SDF");
}
}
Ну... Тут, наверное, придется исходный текст из буфера обмена резать как-то по другому. Приведенный код считает что новая строка в тексте - это новая строка в датагриде.
ОтветитьУдалитьваша слчайно найденная запись здорово помогла мне в работе.
ОтветитьУдалитьспасибо =)
хз конечно, после появление у меня такой задачи я пару минут по гуглил, нашел данный пост, мне показалось это сложным и нашел другой, вернее сам додумал, ниже код (работает на VB 2010)
ОтветитьУдалитьDataGridView1.CurrentCell.Value = My.Computer.Clipboard.GetText()