我们发现了一个涉及DataGridView的可能错误。 DataGridView有一个属性StandardTab,默认情况下设置为False。此默认设置表示TAB键在网格中的单元格之间移动。当它到达网格中的最后一个单元格时,TAB键会将焦点移动到下一个控件。这是我们在项目中使用的设置。
DataGridView连接到我们项目中的绑定源,可能相关也可能不相关。
当DataGridView位于从基于COM的项目(在我们的示例中为VB6)中显示的表单上时,当用户尝试在网格中选项卡时,网格控件将失去焦点。如果按住Tab键,焦点将循环显示表单上的其他控件,直到它返回到网格。当它返回到网格时,所选单元格是用户正在选中的单元格。
因此,当用户从一个单元格移动到另一个单元格时,用户可以通过绕过窗体上的其他控件来浏览所有单元格。这不适合快乐的用户。
我确实发现MSDN forum question似乎描述了这个问题,但唯一的答案并不是非常有帮助。
我可以将此作为Microsoft Connect上的错误提交,但我怀疑他们是否会修复它。有没有办法在代码中处理这个问题?
答案 0 :(得分:2)
对以下事件/方法的进一步调查揭示了一种模式: 离开(在控件上) ProcessDialogKey(在窗体和控件上) ProcessDataGridViewKey(在控件上)
最后两个事件证明是问题的关键。
当我们在100%.NET项目中测试时,我们发现内部的Tab键会执行要触发的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