Reputation: 1
I've tried every suggestion I could think of or could find online to solve this problem, without success.
I use ShowDialog to display a form. The first time the form is displayed, it works OK - the first textbox has a blinking cursor and is ready for input. The form is closed by one of two buttons or the ControlBox "X". Every time the form is displayed after the first time, the cursor is in the textbox, but is frozen. Pressing almost any key will unfreeze the cursor, but the Enter key, spacebar, and up and down arrows all bring up the form's context menu ("Restore", "Move", ... , "X Close") instead. Removing the ControlBox solves the problem (Setting "ControlBox" to False in Properties window), but I don't want to do that. Possibly the ControlBox has the focus???
Initially, if the form was closed using a button, that button had focus the next time the form was opened. I added the line Me.ActiveControl = TextBox1
to the form's Load event. This prevented the buttons from having focus. I also tried adding Me.Show
before Me.ActiveControl = TextBox1
, but it had no effect. I tried setting the active control in the form's Activated and Shown event handlers, but it made no difference. I also tried TextBox1.Select()
and TextBox1.Focus()
without success.
Here is a simple program that demonstrates the problem. There are two Windows forms. In the design window, I added a DataGridView (with one column) and a Button to Form1. Here is the code for 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
For Form2, I added 2 textboxes and an "OK" button in the design window. The button is not set as the form's Accept or Cancel button. Here's the code:
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
If you press the button on Form1, it always brings up Form2 with the cursor blinking in TextBox1. In Form2, press the "OK" button or the ControlBox "X" to close it. No problem there.
The problem happens if you go into a cell in the DataGridView, enter edit mode, and press F10 (or F11). The first time it brings up Form2 correctly, but if you close Form2, then press F10 again (while editing DataGridView1), Form2 is displayed with the cursor frozen. At this point, if you press Enter or the spacebar or the up or down arrow keys, the "Restore", "Move", ... , "Close" system menu pops up.
Later Edit: I discovered two pretty strange things -
If I close Form2 without using the mouse (i.e. Tab to the OK button and press Enter) the problem doesn't happen. It only happens if I click on the OK button with the mouse.
If I bring up Form2 by pressing Button1 instead of pressing F10 and then press and release the Alt key, the cursor freezes and the same four keys bring up the system menu. It turns out this works in other programs (I'm using XP), not just mine, provided there is no menustrip on the form. I'm guessing this is an accessibility feature. So now my question is: Why is this program acting as if the Alt key was pressed and is there a way to prevent or correct it?
Upvotes: 0
Views: 3465
Reputation: 1
What I didn't know is that The F10 key (like the Alt key) changes the focus of a form to the menu (if there is one) or the Title Bar icon (if there is one). I added a menustrip with the standard items to Form2 just to verify that this is the case. What I still don't understand is why pressing F10 on Form1 has this effect on Form2. In any event, adding the following code to Form1 solves the problem. In my actual program, I plan to add this code to my own class derived from DataGridView. In that case it won't be necessary to make sure that the form's ActiveControl is the datagridview (which I did do in the following code).
Basically, I just moved the code for processing F10 from the CellKeyDown sub to ProcessCmdKey, and added Return True
to cancel the normal processing of the key. ProcessCmdKey intercepts the F10 key first, so the other subs (DataGridView1_EditingControlShowing and CellKeyDown) are not needed.
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
Upvotes: 0