2014-01-07 102 views
0

我已經嘗試了每個建議,我可以想到或可以在網上找到解決這個問題,沒有成功。vb.net無法設置焦點窗口文本框

我使用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窗體。在設計窗口中,我添加了一個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個文本框和一個「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上的按鈕,它總是顯示Form2並且TextBox1中的光標閃爍。在Form2中,按下「OK」按鈕或ControlBox「X」關閉它。那裏沒問題。

如果進入DataGridView中的單元格,進入編輯模式並按F10(或F11),則會出現問題。它第一次正確調出Form2,但如果關閉Form2,則再次按F10(在編輯DataGridView1時),Form2將顯示,並且光標被凍結。此時,如果按Enter或空格鍵或上或下箭頭鍵,彈出「恢復」,「移動」,...,「關閉」系統菜單。

後來編輯:我發現了兩個很奇怪的事情 -

  1. 如果我關閉窗體2不使用鼠標(即Tab鍵OK按鈕,然後按Enter)問題不會發生。只有當我用鼠標點擊OK按鈕時纔會發生。

  2. 如果我按下Button1而不是按下F10來調出Form2,然後按下並釋放Alt鍵,光標會凍結,並且相同的四個按鍵將顯示系統菜單。事實證明,這適用於其他程序(我使用XP),不僅僅是我的,只要在表單上沒有菜單欄。我猜這是一個輔助功能。所以現在我的問題是:爲什麼這個程序的行爲就像按下了Alt鍵一樣,並且有辦法阻止或糾正它?

+0

嘗試將YourTextbox.Focus放在Form_Shown事件上。 – SomeNickName

+0

已經嘗試過。 – Terry

+0

發佈相關代碼而不是僅僅描述它通常很有幫助。 –

回答

0

什麼我不知道的是,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