vb.net无法将焦点设置为windows窗体文本框

vb.net无法将焦点设置为windows窗体文本框,vb.net,datagridview,focus,controlbox,Vb.net,Datagridview,Focus,Controlbox,为了解决这个问题,我尝试了所有我能想到的或能在网上找到的建议,但都没有成功 我使用ShowDialog来显示表单。第一次显示表单时,它工作正常-第一个文本框有一个闪烁的光标,可以输入。表单由两个按钮之一或控制框X关闭。每次在第一次显示表单后,光标都位于文本框中,但被冻结。按几乎任何键都会解冻光标,但回车键、空格键和上下箭头都会显示窗体的上下文菜单“还原”、“移动”,X关闭。删除ControlBox解决了在属性窗口中将ControlBox设置为False的问题,但我不想这样做。控制盒可能有焦点 最

为了解决这个问题,我尝试了所有我能想到的或能在网上找到的建议,但都没有成功

我使用ShowDialog来显示表单。第一次显示表单时,它工作正常-第一个文本框有一个闪烁的光标,可以输入。表单由两个按钮之一或控制框X关闭。每次在第一次显示表单后,光标都位于文本框中,但被冻结。按几乎任何键都会解冻光标,但回车键、空格键和上下箭头都会显示窗体的上下文菜单“还原”、“移动”,X关闭。删除ControlBox解决了在属性窗口中将ControlBox设置为False的问题,但我不想这样做。控制盒可能有焦点

最初,如果使用按钮关闭表单,则该按钮在下次打开表单时具有焦点。我将行Me.ActiveControl=TextBox1添加到表单的加载事件中。这使按钮无法对焦。我还尝试添加Me.Show before Me.ActiveControl=TextBox1,但没有效果。我尝试在窗体的已激活和已显示的事件处理程序中设置活动控件,但没有效果。我还尝试了TextBox1.Select和TextBox1.Focus,但没有成功

下面是一个简单的程序来演示这个问题。有两个窗口窗体。在设计窗口中,我向Form1添加了一个DataGridView,其中有一列和一个按钮。以下是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,我在设计窗口中添加了两个文本框和一个OK按钮。该按钮未设置为窗体的“接受”或“取消”按钮。代码如下:

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上的按钮,它总是会在TextBox1中显示Form2,且光标闪烁。在表格2中,按OK按钮或控制框X将其关闭。没问题

如果进入DataGridView中的单元格,进入编辑模式,然后按F10或F11,就会出现问题。第一次正确显示Form2时,如果关闭Form2,然后在编辑DataGridView1时再次按F10,则显示Form2时光标处于冻结状态。此时,如果按Enter键、空格键或向上或向下箭头键,则“还原”、“移动…”,关闭系统菜单弹出

后来编辑:我发现了两件非常奇怪的事情-

如果我在不使用鼠标的情况下关闭Form2,即按下OK按钮的Tab键并按Enter键,则不会出现问题。只有当我用鼠标点击OK按钮时才会发生这种情况

如果我通过按按钮1而不是按F10来调出Form2,然后按下并释放Alt键,光标将冻结,相同的四个键将调出系统菜单。事实证明,这在我使用XP的其他程序中也有效,而不仅仅是我的程序,只要表单上没有菜单提示。我猜这是一个辅助功能。所以现在我的问题是:为什么这个程序就像按下了Alt键一样,有没有办法防止或纠正它


我不知道的是,F10键(如Alt键)会将窗体的焦点更改为菜单(如有),或标题栏图标(如有)。我在Form2中添加了一个带有标准项的menustrip,只是为了验证情况是否如此。我仍然不明白的是,为什么在Form1上按F10会对Form2产生这种影响。在任何情况下,将以下代码添加到Form1都可以解决问题。在我的实际程序中,我计划将此代码添加到我自己从DataGridView派生的类中。在这种情况下,不需要确保窗体的ActiveControl是datagridview,我在下面的代码中就是这么做的

基本上,我只是将处理F10的代码从CellKeyDown子对象移动到ProcessCmdKey,并添加了Return True以取消对键的正常处理。ProcessCmdKey首先截取F10键,因此不需要其他子项DataGridView1\u 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

试着放上你的文本框。关注表单显示的事件。发布相关代码而不仅仅是描述它通常是有帮助的。这很奇怪,在我的作品中。。。问题是,当你加载第二个表单时,它会冻结,对吗?对。除非我移除控制框。您是否尝试将窗体显示为新的窗体对象?无论何时显示,都应重置所有属性。