title: Why does my custom DataGridViewEditingControl never receive KeyDown events for the Enter Key?
body: <p>I have a custom DataGridView editing control which uses the Enter key for some of its functionality. It implements the <code>IDataGridViewEditingControl</code> interface method '`EditingControlWantsInputKey' using the following code:</p>
  
  <pre><code>public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
  {
      switch (keyData &amp; Keys.KeyCode)
      {
          case Keys.Left:
          case Keys.Right:
          case Keys.Up:
          case Keys.Down:
          case Keys.Home:
          case Keys.End:
          case Keys.Enter:
          case Keys.Delete:
              return true;
  
          default:
              return !dataGridViewWantsInputKey;
      }
  }
  </code></pre>
  
  <p>However, it never receives the KeyDown event for the Enter key. I've put a conditional breakpoint in the <code>EditingControlWantsInputKey</code> method to see if the data grid view was ever calling it to find out if I want to respond to the Enter key only to find out it is never called.</p>
  
  <p>In my editing control, I overrode the <code>ProcessCmdKey</code> method to see if the underlying <code>Message</code> was being sent to the control with the following code.</p>
  
  <pre><code>protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
  {
      if ((msg.Msg == User32.WM_KEYDOWN) &amp;&amp;
          ((Keys)msg.WParam == Keys.Enter))
      {
          Console.WriteLine("GOT HERE");
      }
  
      return base.ProcessCmdKey(ref msg, keyData);
  }
  </code></pre>
  
  <p>It is in-fact getting the message, but it is never sent to the <code>OnKeyDown</code> method.</p>
  
  <p>At one point I thought the <code>DataGridView</code> may have been registering a <code>IMessageFilter</code> to handle the key itself, but if that were the case, the control would get the call to <code>ProcessCmdKey</code> (I checked this myself by adding my own <code>IMessageFilter</code>).</p>
  
  <p>Does anyone know what the DataGridView is doing to prevent my custom editing control from getting the call to <code>OnKeyDown</code> and if there is a way to change that behavior?</p>
  
  <p>The only thing I can think of is to handle the routing of the message myself from the <code>ProcessCmdKey</code> method, but that just feel hackish.</p>
  
  <p>[Edit]</p>
  
  <p>To answer King King's comment:</p>
  
  <p>The editing control is a custom subclass of a <code>TextBox</code>. The custom subclass works simply by adding more advanced auto-complete functionality (better than the built in support for a <code>TextBox</code>). The custom text box uses the KeyDown event to know when the user wants to select a suggested auto-complete item. It is used several other places in the application has been used in production code for months (so I'm pretty confident that it is not the culprit).</p>
  
  <p>[Edit - with sample code]</p>
  
  <p>I've constructed a minimal program which seems to show this happening. Create a new WinForms project and put a DataGridView in the Form. Sorry for the wall of code, but this is bare minimal needed to see the effect.</p>
  
  <p>If ran, you'll notice that <code>EditingControlWantsInputKey</code> will never get called for the <code>CustomEditingControl</code> when the key code is Enter, <code>OnKeyDown</code> won't be called, but <code>ProcessCmdKey</code> will be called.</p>
  
  <pre><code>public partial class Form1 : Form
  {
      public Form1()
      {
          InitializeComponent();
  
          dataGridView.EditingControlShowing += this.DataGridView_EditingControlShowing;
      }
  
      private void DataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
      {
          // Must remove first to avoid adding the same event handler twice.
          e.Control.KeyDown -= this.EditingControl_KeyDown;
          e.Control.KeyDown += this.EditingControl_KeyDown;
      }
  
      private void EditingControl_KeyDown(object sender, KeyEventArgs e)
      {
          Console.WriteLine(e.KeyData);
      }
  }
  
  public class CustomEditingControl : DataGridViewTextBoxEditingControl
  {
      public override bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
      {
          if ((Keys.KeyCode &amp; keyData) == Keys.Enter)
          {
              Console.WriteLine("EditingControlWantsInputKey: Enter");
          }
          else
          {
              Console.WriteLine("EditingControlWantsInputKey: Other");
          }
  
          return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey);
      }
  
      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
          const int WM_KEYDOWN = 0x0100;
  
          if ((msg.Msg == WM_KEYDOWN) &amp;&amp;
              ((Keys)msg.WParam == Keys.Enter))
          {
              Console.WriteLine("ProcessCmdKey: Enter");
          }
  
          return base.ProcessCmdKey(ref msg, keyData);
      }
  
      protected override void OnKeyDown(KeyEventArgs e)
      {
          if (e.KeyCode == Keys.Enter)
          {
              Console.WriteLine("OnKeyDown: Enter");
          }
          else
          {
              Console.WriteLine("OnKeyDown: Other");
          }
  
          base.OnKeyDown(e);
      }
  }
  
  public class CustomDataGridViewTextBoxCell : DataGridViewTextBoxCell
  {
      public override Type EditType
      {
          get
          {
              return typeof(CustomEditingControl);
          }
      }
  }
  
  public class CustomDataGridViewColumn : DataGridViewTextBoxColumn
  {
      public CustomDataGridViewColumn()
      {
          this.CellTemplate = new CustomDataGridViewTextBoxCell();
      }
  }
  </code></pre>
  
  <p>[Edit - with more findings]</p>
  
  <p>I added as much logging as I could to the message chain. For a normal text box, pressing the Enter key results in a message trail like the following:</p>
  
  <pre><code>PreFilterMessage: Return
  PreProcessMessage: Return
  ProcessCmdKey: Return
  WndProc: Return
  ProcessKeyPreview: Return
  OnKeyDown: Return
  </code></pre>
  
  <p>For the editing control pressing the '1' key (for example) yields the following trail:</p>
  
  <pre><code>PreFilterMessage: D1
  PreProcessMessage: D1
  ProcessCmdKey: D1
  WndProc: D1
  EditingControlWantsInputKey: D1
  ProcessKeyPreview: D1
  OnKeyDown: D1
  EditingControl_KeyDown: D1 (This is from the hooked up event handler)
  </code></pre>
  
  <p>For the editing control pressing the 'Enter' key yields the following trail</p>
  
  <pre><code>PreFilterMessage: Return
  PreProcessMessage: Return
  ProcessCmdKey: Return
  </code></pre>
  
  <p>So something (presumably the DataGridView) is capturing the message between the <code>ProcessCmdKey</code> and the <code>WndProc</code> methods.</p>