对以下事件/方法的进一步调查揭示了一种模式: Leave(在控件上) ProcessDialogKey(在窗体上和控件上) ProcessDataGridViewKey(在控件上)
最后两个事件被证明是问题的关键。
当我们在一个 100% 的 .NET 项目中进行测试时,我们发现内部选项卡会执行 ProcessDataGridViewKey 事件来触发。在最后一个单元格上时,没有执行 ProcessDataGridView 函数,而是执行了 ProcessDialogKey 函数。
我们在Interop项目中测试的时候,事件是一模一样的,但是在ProcessDataGridViewKey函数执行之前,控件上发生了一个Leave事件。糟糕的情况是独一无二的,因为控件将没有焦点,然后执行 ProcessDataGridViewKey 函数。
也许我们可以对此进行测试并使焦点回到控件上?事实证明我们可以,这里有一个处理它的子类控件,但在 100% .NET 项目中仍然可以正常工作。
Public Class DataGridViewCustom : Inherits DataGridView
Protected Overrides Function ProcessDataGridViewKey(e As System.Windows.Forms.KeyEventArgs) As Boolean
' When the grid is hosted by a form that is being loaded through the Interop Forms Toolkit,
' the default behavior of using the TAB key to navigate between cells is broken
' (StandardTab = False). The tab key causes the grid control to lose focus before it has a
' chance to process the tab key in this event handler.
'
' This handler is not executed when the TAB key is supposed to make it lose focus (i.e. when
' StandardTab is True or when TABbing off the last cell within the grid). In those
' scenarios, the ProcessDialogKey event handler is executed, and there is no problem.
' Therefore, we can assume that if this event is being processed, and the grid does not have
' focus, we should put focus back on the control.
' The datagridview has different behavior for TAB and CTL-TAB, depending on how the StandardTab
' property is set. We don't have to worry about that becuase this method only executes when the
' focus is supposed to stay within the control. A different method is executed when the focus
' is supposed to leave the control.
If e.KeyCode = Keys.Tab AndAlso Not Me.Focused Then Me.Focus()
Return MyBase.ProcessDataGridViewKey(e)
End Function
End Class