Панель не получает фокус
Я продолжаю программировать какую-то навигацию по клавиатуре в моей простой графической программе (используя C #). И я снова столкнулся с проблемой.
Моя проблема в том, что я хочу обработать ввод с клавиатуры, чтобы перемещать слой вокруг. Перемещение слоя с помощью мыши уже работает достаточно хорошо, но элемент управления не получает фокуса (для этого элемента не запускаются ни KeyUp / KeyDown / KeyPress, ни GotFocus / LostFocus ). Поскольку мой class происходит из Panel (и перезаписывает пару событий), я также перезаписал события, упомянутые выше, но мне не удается добиться этих событий.
- Изменить размер для строки состояния вызова?
- как удалить тень под панелью действий с помощью AppCompat.Light.NoActionBar?
- Как оживить Burger в Arrow с помощью Appcompat v7 21, панели инструментов и DrawerLayout
- self.title устанавливает заголовок navigationController и tabBarItem? Зачем?
- Избегайте панели в autoHide в расширении Firefox
Я думаю, что мне удастся реализовать ответ клавиатуры, используя что-то вроде Keyboard.GetState () или ProcessCmdWnd или что-то в этом роде. Однако: я все еще должен быть в состоянии сказать, когда управление получило фокус.
Есть ли более или менее элегантный способ добавить эту способность к пользовательскому элементу управления (который основан на панели)?
Я проверил множество streamов здесь, и я мог бы использовать этот подход для ввода с клавиатуры. Однако проблема фокусировки сохраняется.
Большое вам спасибо за информацию заранее!
Игорь.
ps: Я программирую на C # .NET v3.5, используя VS2008. Это приложение Windows.Forms, а не WPF .
- Как установить текст панели инструментов и цвет стрелки назад
- Цвет выбранной вкладки в нижней навигации
- Добавление вертикальной полосы прокрутки в AlertDialog в Android?
- Чат клиента смайликов окно JAVA
- c: forEach внутри перьев (например, p: panelgrid) внутри ui: repeat
- В каком порядке панели наиболее эффективны с точки зрения времени и производительности?
- Как скрыть строку состояния iOS
- Как исправить метод getActionBar может вызвать java.lang.NullPointerException
Класс 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