首页 > 解决方案 > 检测何时选择 DataGridViewCell/在 VB.Net 中获得焦点

问题描述

在我正在处理的项目中,我创建了一个屏幕键盘,用于输入 TextBoxes 或 DataGridViewCells。

我试图实现这一点的方法是使用一些方法和变量。首先有一个名为的全局变量CurrentFocus,它是一个对象,它被设置为具有键盘可以键入的最新焦点的任何对象。LastFocus创建此变量是因为VB.Net中似乎没有样式方法。

CurrentFocus通过向文本框添加简单的事件处理程序来设置值,我将通过以下方式键入数据:

Dim randomTextbox As New Textbox
AddHandler randomTextbox.GotFocus, AddressOf TextboxGainsFocus

Private Sub TextboxGainsFocus(sender as Textbox, e As EventArgs)
    CurrentFocus = sender
End Sub

至于输入文本框本身,键盘上的每个键都会调用以下方法,参数值是被按下的任何键的大写(因此按下“B”键会发送“B”作为参数)

Private Sub KeypadPress(ByCal key As Char)
    If TypeOf CurrentFocus Is TextBox Then
        If Char.IsDigit(key) Then
            CType(CurrentFocus, Textbox).Text &= key
        Else
            If shiftActive Then
                CType(CurrentFocus, Textbox).Text &= key
            Else
                CType(CurrentFocus, Textbox).Text &= Char.ToLower(key)
            End If
        End If
    End If
End Sub

我没有办法轻松设置按住的 shift 键,因此我将“Shift”设置为就像 Caps Lock 一样,您只需将其打开或关闭即可。这就是shiftActive布尔值的目的。

现在所有上述代码都可以正常工作。我现在的问题是我无法让它与 DataGridViewCells 一起使用。首先,我尝试将类似的 EventHandler 添加到我正在使用的数据网格中

Dim randomGrid As New DataGridView
AddHandler randomGrid.GotFocus, AddressOf GridGainsFocus

Private Sub GridGainsFocus(sender As DataGridView, e As EventArgs)
    CurrentFocus = sender.CurrentCell
End Sub

我已经尝试在检测何时是 DataGridViewCellElseIf的方法中添加一个案例。这很好用。我的问题是它要么没有选择正确的单元格,要么就是什么都不做。KeypadPressCurrentFocus

例如,假设我的 DataGridView 中有 3 行和 3 列。我选择单元格 (2,2),然后按键盘上的一个键。如果我放一个断点来查看方法触发CurrentFocus时的值是多少,它显示为 Cell (0,0)。KeypadPressCurrentFocus

不过,这并不总是发生。有时我确实将它随机(而且看起来确实是随机的)设置为正确的单元格,但尝试像

CType(CurrentFocus, DataGridViewCell).Value &= key

在我的 Keypress 方法中没有做任何事情来改变 DataGridViewCell 的值。

那么我到底需要做什么呢?有没有办法将每个 Cell 设置为拥有自己的处理程序并让它以这种方式工作?我将如何做到这一点,以便我可以修改单元格本身的值?

感谢您的帮助。

标签: vb.netdatagridviewevent-handling

解决方案


所以我想出了如何解决我的问题,我会为将来遇到这个问题的任何人一步一步地解决这个问题。

首先,我向我的 DataGridView 添加了一个事件处理程序,它的工作方式类似于我的文本框的事件处理程序。

Dim exGrid As DataGridView
AddHandler exGrid.CellEnter, AddressOf GridGainsFocus

Private Sub GridGainsFocus(sender As DataGridView, e As EventArgs)
    CurrentFocus = sender.CurrentCell
End Sub

其工作方式是 DataGridViewCells无法获得焦点。只有 DataGridView 本身可以获得焦点。相反,当它们被“聚焦”时,细胞本身被设置为“选定”。因此,您需要使用CellEnter每当用户选择单元格时触发的事件。现在进入我的 Keypress 方法。

Private Sub KeypadPress(ByVal key As Char)
    If TypeOf CurrentFocus Is TextBox Then
        Me.ActiveControl = CurrentFocus
        If Char.IsDigit(key) Then
            SendKeys.SendWait(key)
        Else
            If shiftActive Then
                SendKeys.SendWait(key)
            Else
                SendKeys.SendWait(Char.ToLower(key))
            End If
        End If
    ElseIf TypeOf CurrentFocus Is DataGridViewCell Then
        If CType(CurrentFocus, DataGridViewCell).ReadOnly = False THen
            If Char.IsDigit(key) Then
                If CType(CurrentFocus, DataGridViewCell).Value.Equals(0) Then
                    CType(CurrentFocus, DataGridViewCell).Value = key
                Else
                    CType(CurrentFocus, DataGridViewCell).Value &= key
                End If
            End If
        End If
    End If
End Sub

所以我会从上到下讨论这个。首先,您会注意到我在尝试将数据输入到 TextBox 时修改了处理按键的代码。这是因为对于我的文本框,我将它们设置为具有自动完成数据以帮助搜索数据。我在原始问题中提出的第一个设置不允许使用自动完成数据,因为没有触发实际的按键。

因此,通过我所做的更改,代码现在执行以下操作:

  1. 当按下按钮时,如果CurrentFocus对象是 TextBox 类型,则它将当前焦点更改为该对象。
  2. 触发 SenKey 事件。这将触发文本框自动完成。

现在为 DataGridViewCells。当我CurrentFocus使用我的方法将对象设置为 DataGridViewCell 时GridGainsFocus,该对象存储了对该单元格的完美引用。所以我需要做的就是修改那个 Cell 的值。

现在为了我的程序的目的,我只希望用户将数字值放入单元格中,这就是我有IsDigitif 语句的原因。具体If value.Equals(0)设置为当单元格中有默认值0时,单击'5'键不会将文本输入设置为'05',而是设置为'5'。


推荐阅读