0

Using VS2010 framework 4 VB.net. I have a text box and a datagridview control on a form. I need to trap a CR (enter key press) in the following cases:

1) When the cursor is in a cell on the datagridview.

2) When the cursor is in a text box.

3) When the cursor(focus) is on the form.

The real basis of the issue is the need to override the datagridview's CR behavior as natively it both swallows the CR(making it difficult to trap) and it moves the cursor to the cell below(when the enter key is pressed). I have had some success when using some code posted here which traps all instances of a CR:

Detecting Enter keypress on VB.NET

Here is the accepted solution from the above post with a debug.print addition:

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, _
                                       ByVal keyData As System.Windows.Forms.Keys) _
                                       As Boolean

If msg.WParam.ToInt32() = CInt(Keys.Enter) Then
    'deal with enter key presses here......
     Debug.Print("Active: " & ActiveControl.Name.ToString & " " & Len(ActiveControl.Name.ToString))
    Return True
End If
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

The above solution traps ALL key presses on the form even when they come from a text box, the form itself or the datagridview control. But I need to determine the control from which the CR originated. I see that HWnd is passed in the ProcessCmdKey function(msg.HWnd), but the values it returns do not seem to correspond to the .handle value of any of the originating controls (textbox1.handle or the me.handle or the datagridview1.handle). Upon further reading it appears that this is not a valid comparison.

I have also tried to use the activecontrol.name method to obtain the currently active control and deduce which control sent the CR. However, even with the cursor planted in a cell in the datagridview and sending CRs from the cell, activecontrol.name returns a zero length string. It does however return the name of the text box when I enter a CR from the text box.

How can I determine which control sent the msg?

Much Thanks!

Community
  • 1
  • 1
bartj
  • 27
  • 6

2 Answers2

0

One way to handle this is to make a custom control that inherits datagridview, and add the ProcessCmdKey override function to that control. Then it will only return datagridview keystrokes.

xpda
  • 15,585
  • 8
  • 51
  • 82
0

Use the msg.HWnd property to get the reference to the Control. E.g.

public class MyForm2 : Form {
    TextBox tb = new TextBox();
    Button btn = new Button { Text = "Button" };
    DataGridView dgv = new DataGridView() { Dock = DockStyle.Fill };

    public MyForm2() {
        dgv.Columns.Add("Column1", "Col1");
        dgv.Rows.Add("AAA");
        FlowLayoutPanel p = new FlowLayoutPanel { FlowDirection = FlowDirection.TopDown, Dock = DockStyle.Fill };
        p.Controls.Add(tb);
        p.Controls.Add(btn);
        p.Controls.Add(dgv);
        Controls.Add(p);
    }
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        Control c = Control.FromHandle(msg.HWnd);
        if (keyData == Keys.Enter) {
            if (c == tb)
                MessageBox.Show("TextBox");
            else if (c == btn)
                MessageBox.Show("Button");
            else if (c == dgv || c == dgv.EditingControl) {
                MessageBox.Show("DGV");
            }
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }
}
Loathing
  • 5,109
  • 3
  • 24
  • 35
  • The msg.HWnd data matches the case(.handle) when sending a keypress from a text box, but when sending a keypress from a datagridview control, the msg.HWnd data does NOT match the .handle. The msg.HWnd value is the same when pressing a key from inside the datagridview control as when pressing keys on the form itself. – bartj Sep 10 '15 at 17:07
  • If the `dgv` is currently in edit mode, then you need to compare the control to the `dgv.EditingControl`. Above code is updated. – Loathing Sep 10 '15 at 18:27
  • Using the .EditingControl handle works. Thanks again! – bartj Sep 11 '15 at 15:25
  • Control focusedControl = FindFocusedControl(this); – Henrique May 25 '18 at 15:10