Как предотвратить обработку ввода с клавиатуры (клавиши со стрелками) в форме пользовательского контроля в С#

мой пользовательский элемент управления содержит другие элементы управления, которые можно выбрать, я хотел бы реализовать способ навигации по дочерним элементам управления с помощью клавиш со стрелками

Проблема в том, что родительский контроль перехватывает клавиши со стрелками и использует их для прокрутки своего представления, чего я хочу избежать. Я хочу самостоятельно решить навигацию по содержимому элемента управления.

Как я могу взять под контроль стандартное поведение, вызванное клавишами со стрелками?

Заранее спасибо МТС


person MoreThanChaos    schedule 30.05.2011    source источник
comment
Либо перенаправьте нажатие клавиши, либо установите какое-либо свойство на панели хостинга, чтобы игнорировать события.   -  person CodingBarfield    schedule 30.05.2011


Ответы (2)


Обычно это делается путем переопределения метода IsInputKey(), чтобы сообщить, что вам нужны эти ключи. Однако это не сработает для UserControl, он никогда не получает фокус, поэтому метод OnKeyDown никогда не запускается. Вместо этого переопределите метод ProcessCmdKey(), он вызывается до того, как форма увидит нажатие клавиши. Нравится:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        switch (keyData) {
            case Keys.Left: MessageBox.Show("Left!"); break;
            case Keys.Right: MessageBox.Show("Right!"); break;
            default: return base.ProcessCmdKey(ref msg, keyData);
        }
        return true;  // used
    }
person Hans Passant    schedule 30.05.2011

Вы можете переопределить OnKeyDown в своем пользовательском элементе управления, но это не работает для клавиш со стрелками, потому что они не являются «клавишами ввода» (это клавиши навигации).

Чтобы изменить поведение, переопределите IsInputKey(), чтобы сообщить системе, что вы хотите получать события для клавиш со стрелками:

    protected override bool IsInputKey(Keys keyData)
    {
        bool result = false;

        Keys key = keyData & Keys.KeyCode;

        switch (key)
        {
            case Keys.Up:
            case Keys.Down:
            case Keys.Right:
            case Keys.Left:
                result = true;
                break;

            default:
                result = base.IsInputKey(keyData);
                break;
        }

        return result;
    }
person Edwin Groenendaal    schedule 30.05.2011
comment
Смотрите ответ Ханса Пассана - это тоже сработает. Однако IsInputKey отлично работает в UserControls (только что проверил пример выше) - person Edwin Groenendaal; 30.05.2011
comment
оба ответа решают проблему, тем не менее использование переопределения для ProcessCmdKey кажется более правильным, в любом случае СПАСИБО! - person MoreThanChaos; 30.05.2011