0

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

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

最初,如果使用按钮关闭表单,则该按钮在下次打开表单时具有焦点。我将该行添加Me.ActiveControl = TextBox1到表单的 Load 事件中。这阻止了按钮获得焦点。我也试过添加Me.Showbefore Me.ActiveControl = TextBox1,但没​​有效果。我尝试在表单的 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 上的按钮,它总是会弹出 Form2,而光标在 TextBox1 中会闪烁。在 Form2 中,按“确定”按钮或控制框“X”将其关闭。那里没问题。

如果您进入 DataGridView 中的单元格,进入编辑模式,然后按 F10(或 F11),就会出现问题。第一次正确调出 Form2,但如果关闭 Form2,然后再次按 F10(在编辑 DataGridView1 时),则显示 Form2 并冻结光标。此时,如果按回车键或空格键或上下箭头键,会弹出“恢复”、“移动”、...、“关闭”系统菜单。

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

  1. 如果我在不使用鼠标的情况下关闭 Form2(即 Tab 到 OK 按钮并按 Enter),则不会发生问题。只有当我用鼠标单击 OK 按钮时才会发生这种情况。

  2. 如果我通过按 Button1 而不是按 F10 来调出 Form2,然后按下并释放 Alt 键,则光标会冻结,并且相同的四个键会调出系统菜单。事实证明,这适用于其他程序(我使用的是 XP),而不仅仅是我的,只要表单上没有菜单条。我猜这是一个辅助功能。所以现在我的问题是:为什么这个程序的行为就像按下了 Alt 键一样,有没有办法阻止或纠正它?

4

1 回答 1

0

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

基本上,我只是把处理F10的代码从CellKeyDown子移到ProcessCmdKey中,加上Return True取消对key的正常处理。ProcessCmdKey 先截取 F10 键,所以不需要其他 sub(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
于 2014-01-10T21:13:43.230 回答