Capturing the first character when entering edit mode - a custom edit control in the DataGridView

I have a custom edit control in a DataGridView that for writing is a TextBox and Button together in a UserControl . I inherited from DataGridViewColumn for the new column and DataGridViewTextBoxCell for the new cell.

With a normal DataGridViewTextBoxCell , if you press a key when the cell has focus, it will start editing mode and the character you typed will appear in TextBoxEditingControl . However, in my inherited cell, no value is passed when the key is pressed. (In fact, you need to manually transfer the current cell value to InitializeEditingControl or nothing will appear at all.) So, the first character you enter (the one that starts editing mode) is lost.

I tried OnKeyPress , OnKeyDown and OnKeyUp in a DataGridViewCell , but they are never called. KeyEntersEditMode , however, does seem to trigger the call only when it checks for the key pressed, so this may be a good place to start. Then the problem arises of how to translate KeyEventArgs to char . This is trivial for the alphabet and numbers, but since not all keyboards are created equal, processing other keys is messy and complicated at best. If there is a converter class that does this automatically, please enlighten me.

Has anyone else encountered this problem or found a good workaround?

Note. This issue applies when EditMode is set to any EditOnKeystroke change. Installing in EditOnEnter is a valid EditOnEnter for my project, but I would also like to emulate the default behavior of TextBoxEditingControl .

+4
source share
4 answers

Try setting the KeyPreview parameter of the custom element to true. Then check if the key that starts the editing process starts, even for the user control. If so, you can simply save and assign a character as soon as the text control enters edit mode.

+1
source

My solution is to override OnKeyPress in a custom UserControl .

 protected override void OnKeyPress(KeyPressEventArgs e) { _textBox.Text = e.KeyChar.ToString(); _textBox.SelectionStart = 1; _textBox.SelectionLength = 0; base.OnKeyPress(e); } 
+1
source

Hi Today I had the same problem. My solution is to override KeyEntersEditMode in CustomCell and put some algorithm there to convert or determine if the character is valid to go to the edit control. Then I save this value as a private variable. I override the InitializeEditingControl method and use my stored value as the initial value for the control. After use, I set it to null so that nothing would use it later.

 private string startString; public override bool KeyEntersEditMode(KeyEventArgs e) { var result = base.KeyEntersEditMode(e); if (e.KeyData == Keys.D1) { startString = "1"; } return result; } public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { if(startString != null) { initialFormattedValue = startString; startString = null; } base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); var c = this.DataGridView.EditingControl as MyEditingControl; string initialFormattedValueStr = initialFormattedValue as string; if (initialFormattedValueStr == null) { c.Text = string.Empty; } else { c.Text = initialFormattedValueStr; c.SelectionStart = initialFormattedValueStr.Length; } } 
0
source

To get the first character in your text box, do the following:

1) Add "Imports System.Runtime.InteropServices" or use if you prefer C #

2) Add mapping to SendMessage in user32.dll

 VB.Net example: <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr End Function C# example: [DllImport("USER32.DLL", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

3) Redirect the key to your TextBox from UserControl

 Protected Overrides Function ProcessKeyEventArgs(ByRef m As System.Windows.Forms.Message) As Boolean SendMessage(Me.ComboBox.Handle, m.Msg, m.WParam, m.LParam) Return True End Function protected override bool ProcessKeyEventArgs(ref Message m) { SendMessage(textBox.Handle, m.Msg, m.WParam, m.LParam); return true; } 

4) Here is an example on a Microsoft page using DataGridViewNumericUpDown here , download the source.

5) Done.

0
source

All Articles