2014-01-07 3 views
0

Я пробовал все предложения, которые я мог придумать или мог найти в Интернете, чтобы решить эту проблему без успеха.vb.net Невозможно установить фокус на окно формы текстовое поле

Я использую ShowDialog для отображения формы. При первом отображении формы она работает нормально - в первом текстовом поле есть мигающий курсор и готов к вводу. Форма закрывается одной из двух кнопок или ControlBox «X». Каждый раз, когда форма отображается после первого раза, курсор находится в текстовом поле, но застывает. Нажатие почти любой клавиши размораживает курсор, но клавиши Enter, пробел и стрелки вверх и вниз вызывают контекстное меню формы («Восстановить», «Переместить», ..., «Закрыть»). Удаление ControlBox решает проблему (установка «ControlBox» на False в окне «Свойства»), но я не хочу этого делать. Возможно, у ControlBox есть фокус ???

Первоначально, если форма была закрыта с помощью кнопки, эта кнопка имела фокус, в следующий раз, когда форма была открыта. Я добавил строку Me.ActiveControl = TextBox1 на событие загрузки формы. Это предотвратило фокусировку кнопок. Я также попытался добавить Me.Show до Me.ActiveControl = TextBox1, но это не повлияло. Я попытался установить активный элемент управления в обработчиках событий Activated и Shown, но это не имело никакого значения. Я также пробовал TextBox1.Select() и TextBox1.Focus() без успеха.

Вот простая программа, которая демонстрирует проблему. Существуют две формы Windows. В окне дизайна я добавил DataGridView (с одним столбцом) и Button to 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 нажмите кнопку «ОК» или ControlBox «X», чтобы закрыть его. Нет проблем.

Проблема возникает, если вы войдете в ячейку в DataGridView, войдите в режим редактирования и нажмите F10 (или F11). При первом запуске Form2 правильно, но если вы закроете Form2, а затем снова нажмите F10 (при редактировании DataGridView1), Form2 будет отображаться с заблокированным курсором. На этом этапе, если вы нажмете Enter или пробел или стрелки вверх или вниз, появятся системные меню «Восстановить», «Переместить», ..., «Закрыть».

Позже Edit: я обнаружил две довольно странные вещи -

  1. Если я закрываю Form2 без использования мыши (т.е. Tab к кнопке OK и нажмите Enter) проблема не бывает. Это происходит, только если я нажимаю кнопку ОК с помощью мыши.

  2. Если я вызываю Form2, нажимая Button1 вместо нажатия F10, а затем нажмите и отпустите клавишу Alt, курсор замерзает и все четыре клавиши вызывают системное меню. Оказывается, это работает в других программах (я использую XP), а не только у меня, при условии, что в форме нет menustrip. Я предполагаю, что это функция доступности. Итак, теперь мой вопрос: почему эта программа действует так, как будто нажата клавиша Alt, и есть ли способ ее предотвратить или исправить?

+0

Попробуйте положить YourTextbox.Focus в событие Form_Shown. – SomeNickName

+0

Уже пробовал, что. – Terry

+0

Обычно полезно размещать соответствующий код, а не просто описывать его. –

ответ

0

То, что я не знаю, что ключ F10 (как клавиша Alt) меняет фокус формы в меню (если есть) или значок Title Bar (если есть) , Я добавил menustrip со стандартными элементами в Form2, чтобы убедиться, что это так.Я все еще не понимаю, почему нажатие F10 на Form1 оказывает такое влияние на 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 
Смежные вопросы