检测何时选择了DataGridViewCell /在VB.Net中获得焦点

时间:2019-02-08 14:10:59

标签: vb.net datagridview event-handling

在我正在从事的项目中,我创建了一个屏幕键盘,该键盘可以键入TextBoxes或DataGridViewCells。

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

我通过向文本框添加简单的事件处理程序来设置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

并且我尝试向ElseIf方法中添加KeypadPress大小写,以检测CurrentFocus是何时是DataGridViewCell。很好我的问题是它要么没有选择正确的单元格,要么什么都不做。

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

这并不总是发生。有时我确实将它随机地(并且看起来确实是随机的)设置为适当的单元格,但是尝试类似

CType(CurrentFocus, DataGridViewCell).Value &= key

在我的Keypress方法中,什么都不做来更改DataGridViewCell的值。

那么我到底需要做什么?有没有一种方法可以将每个Cell设置为拥有自己的处理程序,并以这种方式工作?我该怎么做才能修改单元格本身的值?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

所以我想出了解决问题的方式,以后我将逐步为有此问题的任何人解决这个问题。

首先,我向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 无法获得Focus。只有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中输入数据时修改了用于处理按键的代码。这是因为对于我的TextBox,我将它们设置为具有“自动完成”数据以帮助搜索数据。我最初提出的问题中出现的第一个设置不允许使用“自动完成”数据,因为没有触发任何实际的按键操作。

因此,通过更改,我现在执行了以下操作:

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

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

现在就我的程序而言,我只希望用户将数字值放入单元格中,因此这就是为什么我有IsDigit if语句的原因。并将特定的If value.Equals(0)设置为当单元格中的默认值为0时,单击“ 5”键不会将文本输入设置为“ 05”,而是设置为“ 5”。