在我正在进行的项目中,我创建了一个屏幕键盘,用于输入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
我尝试在KeypadPress
方法中添加一个ElseIf
案例,该方法检测CurrentFocus
何时是DataGridViewCell。这很好。我的问题是,它要么没有选择正确的单元格,要么就是什么都不做。
例如,假设我的DataGridView中有3行3列。我选择Cell(2,2),然后按键盘上的键。如果我在KeypadPress
方法触发时放入一个断点来查看CurrentFocus
的值,它会将CurrentFocus
显示为Cell(0,0)。
但这种情况并不总是发生。有时我会随机地(看起来确实是随机的)将其设置为正确的Cell,但尝试之类的东西
CType(CurrentFocus, DataGridViewCell).Value &= key
在我的Keypress方法中,不会对DataGridViewCell的值进行任何更改。
那么我到底需要做什么呢?有没有一种方法可以设置每个Cell,使其拥有自己的处理程序并以这种方式工作?如何修改单元格本身的值?
谢谢你的帮助。
所以我想好了如何解决我的问题,我会为将来有这个问题的人一步一步地研究它。
首先,我在DataGridView中添加了一个事件处理程序,其工作方式与Textboxes的事件处理程序类似。
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
事件,每当用户选择Cell时,该事件就会触发。现在开始我的键盘法。
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时,我修改了用于处理按键的代码。这是因为对于我的文本框,我将它们设置为具有自动完成数据,以帮助搜索数据。我在最初的问题中提出的第一个设置不允许使用自动完成数据,因为没有触发实际的按键。
因此,随着我所做的更改,代码现在如下所示:
- 按下按钮时,如果
CurrentFocus
对象的类型为TextBox,则会将当前焦点更改为该对象 - 触发SenKey事件。这将触发TextBox自动完成功能
现在用于DataGridViewCells。当我用GridGainsFocus
方法将CurrentFocus
对象设置为DataGridViewCell时,该对象会存储对该单元格的完美引用。所以我所需要做的就是修改Cell的值。
现在,就我的程序而言,我只希望用户将数字值放入单元格中,所以这就是为什么我有IsDigit
if语句。具体的If value.Equals(0)
设置为,当单元格中有默认值0时,单击"5"键不会将文本输入设置为"05",而是设置为"5"。