C # фокус в формах и клавишах со стрелками - PullRequest
1 голос
/ 30 марта 2012

Я хочу сделать редактор карт для игры. Это программа, которая будет иметь пользовательский интерфейс Windows Forms (например, propertyGrid для редактирования свойств объекта), но также будет иметь панель, на которой будет отображаться карта.

Что я хочу:

Когда фокус находится на панели с картой, я хотел бы использовать клавиатуру для перемещения карты (клавиши со стрелками), добавлять объекты (цифровые клавиши) и т. Д. Когда фокус не на этой панели, мне нужны кнопки работать как обычно в окнах форм - позволяют переключаться между элементами управления и т. д.

Моя форма выглядит так:

Он имеет ToolStripControl, который имеет menuStrip (для главного меню) и statusStrip (для строки состояния). В середине формы (или toolstripcontrol) SplitControl закреплен (dock = fill), который имеет две панели. В Panel 1 есть PanelMap - панель, отображающая карту, в Panel 2 есть все остальные элементы, такие как таблица свойств, управление вкладками, кнопки и т. Д.

У меня KeyPreview формы установлен в true и обрабатывает события клавиатуры в обработчике событий keydown формы.

Теперь, что произойдет, если я назначу фокус на PanelMap, в следующий раз, когда я нажму клавишу со стрелкой, событие KeyDown НЕТ срабатывает. Ни одного! Даже форма, которая должна обрабатывать все события, потому что она имеет «KeyPreview», даже не запускается. Когда я нажимаю стрелку, PanelMap теряет фокус в направлении SplitControl.

Ладно, подумал я, возможно, у PanelMap не должно быть фокуса, давайте дадим фокус SplitControl (если я нажму клавишу со стрелкой, когда у нее есть фокус, я могу обработать ее, чтобы она не пошла дальше). Но затем, если что-то вроде текстового поля внутри чего-то внутри SplitControl имеет фокус, тогда SplitControl НЕ МОЖЕТ получить фокус. .Focus () ничего не сделает - фокус остается в любом элементе управления, который его имел!

Почему это действует так странно? Почему KeyDown формы не срабатывает, когда панель имеет фокус и нажата клавиша со стрелкой? Почему SplitControl не фокусируется, когда я вызываю .Focus (), хотя CanFocus = true?

И в конечном итоге, как мне достичь того, чего я хочу? Есть ли способ сделать это?

Ответы [ 2 ]

1 голос
/ 30 марта 2012

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

    private void RemoveCursorNavigation(Control.ControlCollection controls)
    {
        foreach(Control ctrl in controls)
        {
            ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(MainWin_PreviewKeyDown);
            RemoveCursorNavigation(ctrl.Controls);
        }
    }

Я вызываю эту функцию в обработчике загрузки главной формы, например:

RemoveCursorNavigation(this.Controls);

В вашем обработчике PreviewKeyDown вам нужно сделатьthis:

    public void MainWin_PreviewKeyDown(Object sender, PreviewKeyDownEventArgs e)
    {
        switch(e.KeyCode)
        {
            case Keys.Up:
            case Keys.Down:
            case Keys.Left:
            case Keys.Right:
                e.IsInputKey = true;
                break;
            default:
                break;
        }
    }

e.IsInputKey = true; сообщает извне, что вы использовали это событие, и не хотите, чтобы оно куда-либо направлялось.

Теперь вы можете увидеть нажатия клавиш раньшеони переходят к виджетам, и вы не сможете перемещаться между ними с помощью клавиш курсора.

0 голосов
/ 30 марта 2012

Я нашел ответ, подобный этому:

Я создал текстовое поле, которое скрыто под панелью (но включено и видно).Это текстовое поле получает фокус, когда я хочу «заблокировать» фокус на моей PanelMap.Он имеет onkeydown даже с e.suppress = true, так что текстовое поле никогда не получает никаких нажатий клавиш, чтобы повлиять на него.

Грубый обходной путь, но творит чудеса ... типичный бизнес M $ ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...