Панель не получает фокус

Я продолжаю программировать какую-то навигацию по клавиатуре в моей простой графической программе (используя C #). И я снова столкнулся с проблемой.

alt text

Моя проблема в том, что я хочу обработать ввод с клавиатуры, чтобы перемещать слой вокруг. Перемещение слоя с помощью мыши уже работает достаточно хорошо, но элемент управления не получает фокуса (для этого элемента не запускаются ни KeyUp / KeyDown / KeyPress, ни GotFocus / LostFocus ). Поскольку мой class происходит из Panel (и перезаписывает пару событий), я также перезаписал события, упомянутые выше, но мне не удается добиться этих событий.

Я думаю, что мне удастся реализовать ответ клавиатуры, используя что-то вроде Keyboard.GetState () или ProcessCmdWnd или что-то в этом роде. Однако: я все еще должен быть в состоянии сказать, когда управление получило фокус.

Есть ли более или менее элегантный способ добавить эту способность к пользовательскому элементу управления (который основан на панели)?

Я проверил множество streamов здесь, и я мог бы использовать этот подход для ввода с клавиатуры. Однако проблема фокусировки сохраняется.

Большое вам спасибо за информацию заранее!

Игорь.

ps: Я программирую на C # .NET v3.5, используя VS2008. Это приложение Windows.Forms, а не WPF .

Класс 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); } } } 

Тот же самый код Hans Passant в VB.NET

 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 

фокус вызова в событии click

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

Чтобы получить фокус, проверьте событие MouseEnter в окне «Свойства».

Напишите ниже код:

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

Самый простой трюк, который я использую, когда по какой-либо причине я не могу использовать родительское свойство Form KeyPreview, чтобы сделать ключевые события формы обработкой, заключается в том, чтобы поместить текстовое поле на

Панель:

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

И используйте его для захвата события KeyDown:

 _focusTextBox.KeyDown += panel_KeyDown; 

Последний шаг – установить фокус на этот TextBox, когда другие элементы управления на панели щелкнули:

 _focusTextBox.Focus(); 

Панели не фокусируются, вам нужно выбрать панель, если вы хотите отслеживать отпуск и вводить события

call panel1.Select() в событии MouseClick

Давайте будем гением компьютера.