1

我们发现了一个可能涉及 DataGridView 的错误。DataGridView 有一个属性 StandardTab,默认设置为 False。此默认设置意味着 TAB 键在网格内的单元格之间移动。当它到达网格中的最后一个单元格时,TAB 键将焦点移动到下一个控件。这是我们在项目中使用的设置。

DataGridView 连接到我们项目中的绑定源,这可能相关也可能不相关。

当 DataGridView 位于从基于 COM 的项目(在我们的例子中为 VB6)中显示的窗体上时,当用户尝试在网格中进行选项卡时,网格控件会失去焦点。如果您按住 tab 键,焦点将在表单上的其他控件之间循环,直到它返回到网格。当它返回到网格时,选定的单元格就是用户正在切换到的单元格。

因此,当用户从一个单元格移动到另一个单元格时,用户可以通过绕过表单上的其余控件来浏览所有单元格。这不会让用户满意。

我确实找到了一个似乎描述了这个问题的MSDN 论坛问题,但它的唯一答案并不是很有帮助。

我可以将此作为 Microsoft Connect 上的错误提交,但我怀疑他们是否会修复它。有没有办法在代码中处理这个问题?

4

1 回答 1

2

对以下事件/方法的进一步调查揭示了一种模式: 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
于 2011-11-04T15:18:37.097 回答