当在通过Interop访问的表单上使用时,我们如何处理DataGridView不正确地失去焦点

时间:2011-11-04 15:14:36

标签: winforms datagridview com-interop winforms-interop

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

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

当DataGridView位于从基于COM的项目(在我们的示例中为VB6)中显示的表单上时,当用户尝试在网格中选项卡时,网格控件将失去焦点。如果按住Tab键,焦点将循环显示表单上的其他控件,直到它返回到网格。当它返回到网格时,所选单元格是用户正在选中的单元格。

因此,当用户从一个单元格移动到另一个单元格时,用户可以通过绕过窗体上的其他控件来浏览所有单元格。这不适合快乐的用户。

我确实发现MSDN forum question似乎描述了这个问题,但唯一的答案并不是非常有帮助。

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

1 个答案:

答案 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