In a DataGridView, pressing SHIFT and SPACE will by default select the entire row. The only solution I've found (referenced at vb.net DataGridView - Replace Shortcut Key with typed character) is to turn off the row select feature. While that works, it's not ideal, because I would still like to be able to select the whole row using the row selector (for example, to delete the row), and by changing the SelectionMode
property to anything other than RowHeaderSelect
I lose that ability. Is there a way to trap just the SHIFT+SPACE combination and replace it with a simple SPACE? It seems like none of the key events even recognize that keystroke when the control's MutiSelect
property is set to True
and the SelectionMode
property is set to RowHeaderSelect
, so I can't use those.
ETA: I thought maybe turning off MultiSelect
and changing the selection mode to CellSelect
, then adding an event handler for the RowHeaderMouseClick
event would work...nope.
The best way I figured out how to accomplish this was to inherit from DataGridView and override the ProcessCmdKey method. Then you can intercept the Shift+Space and just send on Space. Just add this class to your project and switch all of your DataGridViews to MyDataGridViews. My solution draws inspiration from this DataGridView keydown event not working in C# SO question (that also explains why Zaggler's solution doesn't work) and this SendKeys in ProcessCmdKey: change Shift-Space to just a Space Bytes.com post. Sorry, but it's in C#.
class MyDataGridView : System.Windows.Forms.DataGridView
{
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
if (keyData == (System.Windows.Forms.Keys.Space | System.Windows.Forms.Keys.Shift))
{
// DataGridView is dumb and will select a row when the user types Shift+Space
// if you have the DGV set so that you can click a row header to select a row (for example, to delete the row)
// this method will intercept Shift+Space and just send on Space so that the DGV properly handles this.
// For example, if I type "ME TYPING IN ALL CAPS" it ends up looking like "METYPINGINALLCAPS".
// Or if I type "Note: I have some OS thing to talk about" it looks like "Note:Ihave some OSthing to talk about"
byte[] keyStates = new byte[255];
UnsafeNativeMethods.GetKeyboardState(keyStates);
byte shiftKeyState = keyStates[16];
keyStates[16] = 0; // turn off the shift key
UnsafeNativeMethods.SetKeyboardState(keyStates);
System.Windows.Forms.SendKeys.SendWait(" ");
keyStates[16] = shiftKeyState; // turn the shift key back on
UnsafeNativeMethods.SetKeyboardState(keyStates);
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
[System.Security.SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetKeyboardState(byte[] keystate);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int SetKeyboardState(byte[] keystate);
}
}
This was my solution:
private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
dataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;
}
private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dataGridView.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With