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;
}
}
}
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;
}
}
}