web-dev-qa-db-ja.com

パネルがフォーカスされない

単純なグラフィックプログラムで(C#を使用して)ある種のキーボードナビゲーションをプログラムし続けています。そしてまたトラブルに遭遇しました。

alt text

私の問題は、キーボード入力を処理してレイヤーを移動することです。マウスでレイヤーを移動することは既に非常にうまく機能していますが、コントロールはフォーカスを取得しません(このコントロールではKeyUp/KeyDown/KeyPressもGotFocus/LostFocusもトリガーされません)。私のクラスはPanelから派生している(そしていくつかのイベントを上書きしている)ため、上記のイベントも上書きしましたが、これらのイベントをトリガーすることに成功できません。

私は、Keyboard.GetState()やProcessCmdWndなどを使用してキーボード応答を実装することができたと思います。ただし、コントロールがいつフォーカスを取得したかはまだわかりません。

この機能をユーザーコントロール(パネルに基づく)に追加するための多少洗練された方法はありますか?

ここで多くのスレッドをチェックしましたが、キーボード入力に このアプローチ を使用する可能性があります。ただし、フォーカスの問題はまだ残っています。

よろしくお願いします!

イゴール。

pS:VS2008を使用して、C#.NET v3.5でプログラミングしています。これはWindows.Formsアプリケーションであり、WPFではありません。

28
Igor

Panelクラスはコンテナとして設計されており、フォーカスを取得しないため、子コントロールは常にそれを取得します。あなたはそれを修正するためにいくつかの手術が必要になります。 KeyDownイベントでもカーソルキーストロークを取得するためにコードをスローしました。

using System;
using System.Drawing;
using System.Windows.Forms;

class SelectablePanel : Panel {
    public SelectablePanel() {
        this.SetStyle(ControlStyles.Selectable, true);
        this.TabStop = true;
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        this.Focus();
        base.OnMouseDown(e);
    }
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Up || keyData == Keys.Down) return true;
        if (keyData == Keys.Left || keyData == Keys.Right) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnEnter(EventArgs e) {
        this.Invalidate();
        base.OnEnter(e);
    }
    protected override void OnLeave(EventArgs e) {
        this.Invalidate();
        base.OnLeave(e);
    }
    protected override void OnPaint(PaintEventArgs pe) {
        base.OnPaint(pe);
        if (this.Focused) {
            var rc = this.ClientRectangle;
            rc.Inflate(-2, -2);
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
        }
    }
}
57
Hans Passant

VB.NETの同じHans Passantコード

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class SelectablePanel
    Inherits Panel

    Public Sub SelectablePanel()
        Me.SetStyle(ControlStyles.Selectable, True)
        Me.TabStop = True
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        Me.Focus()
        MyBase.OnMouseDown(e)
    End Sub

    Protected Overrides Function IsInputKey(ByVal keydata As Keys) As Boolean
        If (keydata = Keys.Up OrElse keydata = Keys.Down) Then Return True
        If (keydata = Keys.Left OrElse keydata = Keys.Right) Then Return True
        Return MyBase.IsInputKey(keydata)
    End Function

    Protected Overrides Sub OnEnter(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnEnter(e)
    End Sub

    Protected Overrides Sub OnLeave(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnLeave(e)
    End Sub

    Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
        MyBase.OnPaint(pe)
        If (Me.Focused) Then
            Dim rc As Rectangle = Me.ClientRectangle
            rc.Inflate(-2, -2)
            ControlPaint.DrawFocusRectangle(pe.Graphics, rc)
        End If
    End Sub

End Class
6
Oliver Miranda

何らかの理由で親のフォームのKeyPreviewプロパティを使用してフォームにキーイベントを処理させることができない場合に使用する最も簡単なトリックは、テキストボックスを配置することです

パネル:

Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0});   

そして、それを使用してKeyDownイベントをキャプチャします。

_focusTextBox.KeyDown += panel_KeyDown;

最後のステップは、パネル上の他のコントロールがクリックされたときに、このTextBoxにフォーカスを設定することです。

_focusTextBox.Focus();
0
Eng. M.Hamdy

クリックイベントでフォーカスを呼び出す

private void Panel_Click(object sender, EventArgs e)
    {
        Panel.Focus();
    }
0
user2462638

フォーカスを取得するには、[プロパティ]ウィンドウでMouseEnterイベントを確認します。

コードの下に書きます:

private void mainPanel_MouseEnter(object sender, EventArgs e)
{
    mainPanel.Focus();
}
0
Digambar Malla