0

この問題を解決するために、考えられる、またはオンラインで見つけることができるすべての提案を試しましたが、成功しませんでした。

ShowDialog を使用してフォームを表示します。フォームが初めて表示されたときは、問題なく動作します。最初のテキスト ボックスにはカーソルが点滅し、入力できる状態になっています。フォームは、2 つのボタンのいずれか、または ControlBox "X" によって閉じられます。フォームが最初に表示されるたびに、カーソルはテキストボックスにありますが、フリーズしています。ほぼすべてのキーを押すとカーソルのフリーズが解除されますが、Enter キー、スペースバー、および上下の矢印はすべて、代わりにフォームのコンテキスト メニュー ("復元"、"移動"、...、"X 閉じる") を表示します。ControlBox を削除すると問題は解決しますが ([プロパティ] ウィンドウで "ControlBox" を False に設定します)、私はそうしたくありません。おそらくControlBoxにフォーカスがありますか???

最初に、ボタンを使用してフォームを閉じた場合、次にフォームを開いたときにそのボタンにフォーカスがありました。Me.ActiveControl = TextBox1フォームの Load イベントに行を追加しました。これにより、ボタンがフォーカスされなくなりました。Me.Showも前に追加してみMe.ActiveControl = TextBox1ましたが、効果がありませんでした。フォームの Activated および Shown イベント ハンドラでアクティブ コントロールを設定しようとしましたが、違いはありませんでした。私も試してみましたが、成功しませんでしたTextBox1.Select()TextBox1.Focus()

この問題を示す簡単なプログラムを次に示します。2 つの Windows フォームがあります。デザイン ウィンドウで、DataGridView (1 列) とボタンを 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 キーまたはスペースバーまたは上下矢印キーを押すと、[復元]、[移動]、[閉じる] というシステム メニューが表示されます。

後で編集:私は2つのかなり奇妙なことを発見しました -

  1. マウスを使用せずに Form2 を閉じると (つまり、Tab キーを押して [OK] ボタンに移動し、Enter キーを押します)、問題は発生しません。マウスで[OK]ボタンをクリックした場合にのみ発生します。

  2. F10 を押す代わりに Button1 を押して Form2 を表示し、Alt キーを押して放すと、カーソルがフリーズし、同じ 4 つのキーでシステム メニューが表示されます。フォームにメニューストリップがない場合、これは私のものだけでなく、他のプログラム(私はXPを使用しています)でも機能することがわかりました。これはアクセシビリティ機能だと思います。だから今私の質問は: なぜこのプログラムは Alt キーが押されたかのように動作し、それを防止または修正する方法はありますか?

4

1 に答える 1

0

私が知らなかったのは、F10 キー (Alt キーのような) は、フォームのフォーカスをメニュー (ある場合) またはタイトル バー アイコン (ある場合) に変更するということです。これが事実であることを確認するためだけに、標準アイテムを含むメニューストリップを Form2 に追加しました。私がまだ理解していないのは、Form1 で F10 を押すと Form2 にこの効果がある理由です。いずれにせよ、次のコードを Form1 に追加すると問題が解決します。実際のプログラムでは、DataGridView から派生した独自のクラスにこのコードを追加する予定です。その場合、フォームの ActiveControl が datagridview であることを確認する必要はありません (次のコードで行いました)。

基本的には、CellKeyDown サブから ProcessCmdKey に F10 を処理するコードを移動し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
于 2014-01-10T21:13:43.230 に答える