Copy and Paste in a DataGridView with Ctrl-C and Ctrl-V

N

neil.stuart

Here is an early attempt at a practical adaptation of this code -
http://groups.google.co.nz/group/mi...5?lnk=st&q=datagridview+"ctrl+C"&rnum=3&hl=en
It seems to work for the simple cases, but has not yet been rigorously
tested with DateTime values...

HTH,
Neil.

using System;
using System.Windows.Forms;

namespace <Namespace>
{
/// <summary>An inherited DataGridView class which initially allows
for simple copy and paste operations,
/// without having to select the contents of the cell first. If
more than once cell was selected during the
/// copy, the control will attempt to paste the values into
subsequent cells</summary>
/// <remarks>Customise the PerformPaste method if you expect
something other than text on the clipboard,
/// or you need something other than strings, most number types or
datetimes to be pasted.
/// It does not behave entirely well if the paste selection is more
than a single cell.</remarks>
public class CopyAndPasteDataGridView : DataGridView
{
private bool _ctrlDown = false;
private bool _shiftDown = false;

/// <summary>This override will be called once for each key
press in the DataGridView, so the typical
/// flow will be modifier key pressed (WM_KEYDOWN), other key
pressed (WM_KEYDOWN), other key released
/// (WM_KEYUP), modifier key released (WM_KEYUP). When the
modifier key is released the persistent
/// flag for that key is unset.</summary>
protected override void WndProc(ref Message m)
{
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
const int WM_PASTE = 0x0302;

bool handledMessage = false;

switch (m.Msg)
{
case WM_KEYDOWN:
if ((int)m.WParam == (int)Keys.ControlKey)
{
_ctrlDown = true;
break;
}

if ((int)m.WParam == (int)Keys.ShiftKey)
{
_shiftDown = true;
break;
}

if (_ctrlDown && ((int)m.WParam == (int)Keys.V))
{
handledMessage = PerformPaste();
}
else if (_shiftDown && ((int)m.WParam ==
(int)Keys.Insert))
{
handledMessage = PerformPaste();
}
break;

case WM_KEYUP:
if ((int)m.WParam == (int)Keys.ControlKey)
{
_ctrlDown = false;
}
else if ((int)m.WParam == (int)Keys.ShiftKey)
{
_shiftDown = false;
}
break;

case WM_PASTE:
handledMessage = PerformPaste();
break;
}

if (handledMessage)
{
//All of these messages expect a 0 return if the
message was handled
m.Result = new IntPtr(0);
}
else
{
base.WndProc(ref m);
}
}

/// <summary>Inspect the clipboard contents, and attempt to
paste value(s) to the datagrid if the clipboard
/// contains text</summary>
/// <returns>True, if a value was pasted, false
otherwise</returns>
/// <remarks>All of the contents of the datagrid can be
examined from here, so complex decisions can be made
/// if necessary.</remarks>
private bool PerformPaste()
{
bool success = false;

if (Clipboard.ContainsText())
{
//If more than one cell was selected during the copy
then the contents of each cell are separated
//by a newline
string text = Clipboard.GetText();
string[] peices = text.Split('\t');

int i = 0;
foreach (string peice in peices)
{
if ((this.CurrentCell.ColumnIndex + i) <
this.Columns.Count)
{
DataGridViewCell pasteTarget =
this.Rows[this.CurrentCell.RowIndex].Cells[this.CurrentCell.ColumnIndex
+ i];

//This also, rather convienently, avoids errors
with ComboboxColumns as they typically have
//ValueTypes of int, while the display value
(which is what is on the clipboard) does not
//parse successfully to int
if (pasteTarget.ValueType == typeof(string))
{
pasteTarget.Value = peice;
success = true;
}
else if (pasteTarget.ValueType == typeof(int))
{
int parsed;
if (int.TryParse(peice, out parsed))
{
pasteTarget.Value = parsed;
success = true;
}
}
else if (pasteTarget.ValueType ==
typeof(double))
{
double parsed;
if (double.TryParse(peice, out parsed))
{
pasteTarget.Value = parsed;
success = true;
}
}
else if (pasteTarget.ValueType ==
typeof(decimal))
{
decimal parsed;
if (decimal.TryParse(peice, out parsed))
{
pasteTarget.Value = parsed;
success = true;
}
}
else if (pasteTarget.Value == typeof(DateTime))
{
DateTime parsed;
if (DateTime.TryParse(peice, out parsed))
{
pasteTarget.Value = parsed;
success = true;
}
}
}
i++;
}
}

return success;
}

}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top