繁体   English   中英

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

[英]vb.net Can't set focus to windows form textbox

我尝试了所有我能想到的建议或可以在网上找到的解决此问题的建议,但都没有成功。

我使用ShowDialog显示表单。 第一次显示该表单时,它可以正常工作-第一个文本框的光标闪烁并且可以输入。 通过两个按钮之一或ControlBox“ X”关闭该表单。 第一次之后每次显示表单时,光标都在文本框中,但被冻结。 几乎按任何键都可以解冻光标,但是Enter键,空格键和向上和向下箭头都可以调出窗体的上下文菜单(“还原”,“移动”,...,“ X关闭”)。 删除ControlBox可解决问题(在“属性”窗口中将“ ControlBox”设置为False),但我不想这样做。 可能ControlBox具有焦点???

最初,如果使用按钮关闭了表单,则下次打开表单时,该按钮将成为焦点。 我将Me.ActiveControl = TextBox1行添加到窗体的Load事件。 这使按钮无法获得焦点。 我还尝试在Me.ActiveControl = TextBox1之前添加Me.Show ,但这没有任何效果。 我尝试在窗体的Activated和Shown事件处理程序中设置活动控件,但没有区别。 我也尝试了TextBox1.Select()TextBox1.Focus()但没有成功。

这是一个演示该问题的简单程序。 有两种Windows窗体。 在设计窗口中,我向Form1添加了一个DataGridView(带有一列)和一个Button。 这是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上的按钮,它总是在光标在TextBox1中闪烁的情况下弹出Form2。 在Form2中,按“确定”按钮或ControlBox“ X”将其关闭。 没问题。

如果您进入DataGridView中的单元格,进入编辑模式,然后按F10(或F11),则会发生问题。 第一次正确启动Form2,但是如果关闭Form2,然后再次按F10(在编辑DataGridView1时),则会显示Form2,并且光标处于冻结状态。 此时,如果按Enter键或空格键或向上或向下箭头键,将弹出“恢复”,“移动”,...,“关闭”系统菜单。

后来编辑:我发现了两个非常奇怪的东西-

  1. 如果我不使用鼠标就关闭Form2(即,按Tab键进入“确定”按钮,然后按Enter键),则不会发生此问题。 仅当我用鼠标单击“确定”按钮时才会发生。

  2. 如果我通过按Button1而不是按F10调出Form2,然后按并释放Alt键,则光标将冻结,并且相同的四个键调出系统菜单。 事实证明,这可以在其他程序(我正在使用XP)中工作,而不仅仅是我的,只要表格上没有菜单栏即可。 我猜这是一个可访问性功能。 所以现在我的问题是:为什么该程序的行为就像按下Alt键一样,有什么方法可以防止或纠正它?

我不知道的是F10键(如Alt键)将窗体的焦点更改为菜单(如果有)或标题栏图标(如果有)。 我向Form2添加了带有标准项的菜单条,只是为了验证是否确实如此。 我仍然不明白的是为什么在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM