我已经尝试了我能想到或可以在网上找到解决这个问题的所有建议,但没有成功。
我使用ShowDialog来显示表单。第一次显示表单时,它工作正常 - 第一个文本框有一个闪烁的光标,可以输入。表单由两个按钮之一或ControlBox“X”关闭。每次在第一次显示表单后,光标都在文本框中,但是被冻结。按下几乎任何键都会解冻光标,但是Enter键,空格键和向上和向下箭头都会调出表格的上下文菜单(“恢复”,“移动”,......,“X关闭”)。删除ControlBox解决了问题(在“属性”窗口中将“ControlBox”设置为False),但我不想这样做。可能ControlBox有焦点???
最初,如果使用按钮关闭表单,则下次表单打开时该按钮会有焦点。我将行Me.ActiveControl = TextBox1
添加到表单的Load事件中。这阻止了按钮具有焦点。我还尝试在Me.Show
之前添加Me.ActiveControl = TextBox1
,但它没有效果。我尝试在表单的Activated和Shown事件处理程序中设置活动控件,但它没有任何区别。我还尝试TextBox1.Select()
和TextBox1.Focus()
但没有成功。
这是一个演示问题的简单程序。有两种Windows窗体。在设计窗口中,我添加了一个DataGridView(带有一列)和一个Button到Form1。这是Form1的代码:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As _System.EventArgs) Handles Button1.Click
Dim result As DialogResult
Dim TForm As Form2
TForm = New Form2
result = TForm.ShowDialog
End Sub
Private Sub DataGridView1_EditingControlShowing _
(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView1.EditingControlShowing
If TypeOf e.Control Is TextBox Then
RemoveHandler DirectCast(e.Control, TextBox).KeyDown, AddressOf CellKeyDown
AddHandler DirectCast(e.Control, TextBox).KeyDown, AddressOf CellKeyDown
End If
End Sub
Private Sub CellKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
Select Case e.KeyCode
Case Keys.F10
With DataGridView1
.EndEdit()
Dim result As DialogResult
Dim TestForm2 As Form2
TestForm2 = New Form2
result = TestForm2.ShowDialog
TestForm2 = Nothing
.BeginEdit(False)
Me.ActiveControl = .EditingControl ' This makes the cursor visible
End With
Case Keys.F11
With DataGridView1
.EndEdit()
Dim result As DialogResult
result = Form2.ShowDialog
.BeginEdit(False)
Me.ActiveControl = .EditingControl
End With
End Select
End Sub
End Class
对于Form2,我在设计窗口中添加了2个文本框和一个“确定”按钮。该按钮未设置为表单的“接受”或“取消”按钮。这是代码:
Public Class Form2
Private Sub btnOK_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnOK.Click
Me.Close()
End Sub
Private Sub Form2_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Me.ActiveControl = Me.TextBox1
End Sub
End Class
如果按下Form1上的按钮,它总是会弹出Form2,光标在TextBox1中闪烁。在Form2中,按“确定”按钮或ControlBox“X”将其关闭。没问题。
如果您进入DataGridView中的单元格,进入编辑模式,然后按F10(或F11),则会出现问题。第一次正确显示Form2,但如果关闭Form2,然后再次按F10(编辑DataGridView1时),将显示Form2,光标冻结。此时,如果按Enter键或空格键或向上或向下箭头键,则会弹出“恢复”,“移动”,...,“关闭”系统菜单。
后来编辑:我发现了两件非常奇怪的事情 -
如果我在不使用鼠标的情况下关闭Form2(即Tab键到OK按钮并按Enter键),则不会发生此问题。只有用鼠标点击OK按钮才会发生这种情况。
如果我按下Button1而不是按F10调出Form2,然后按下并释放Alt键,光标会冻结,同样的四个键会调出系统菜单。事实证明这适用于其他程序(我使用XP),而不仅仅是我的,只要表单上没有menustrip。我猜这是一个辅助功能。所以现在我的问题是:为什么这个程序就像按下Alt键一样,是否有办法防止或纠正它?
答案 0 :(得分:0)
我不知道的是F10键(如Alt键)将表单的焦点更改为菜单(如果有)或标题栏图标(如果有的话)。我在Form2中添加了带有标准项目的menustrip,以验证是否属实。我还不明白为什么在Form1上按F10会对Form2产生这种影响。无论如何,将以下代码添加到Form1可以解决问题。在我的实际程序中,我计划将此代码添加到从DataGridView派生的我自己的类中。在这种情况下,没有必要确保表单的ActiveControl是datagridview(我在下面的代码中做过)。
基本上,我只是将处理F10的代码从CellKeyDown子句移动到ProcessCmdKey,并添加了Return True
来取消密钥的正常处理。 ProcessCmdKey首先拦截F10键,因此不需要其他子(DataGridView1_EditingControlShowing和CellKeyDown)。
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
If TypeOf Me.ActiveControl Is DataGridViewTextBoxEditingControl Then
If keyData = Keys.F10 Then
DataGridView1.EndEdit()
Dim TestForm2 As Form2
TestForm2 = New Form2
Dim result As DialogResult
result = TestForm2.ShowDialog
TestForm2.Dispose()
TestForm2 = Nothing
DataGridView1.BeginEdit(False)
Me.ActiveControl = DataGridView1.EditingControl
Return True
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function