簡體   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