Есть ли реализация C # или способ иметь текстовое поле, которое принимает последовательность клавиш в качестве ввода? - PullRequest
0 голосов
/ 05 ноября 2010

У меня есть реализация, которая подключается к событию keydown, которое подавляет событие нажатия клавиш и выполняет некоторые действия. Теперь я хочу показать что-то более дружелюбное, чем «ControlKey» и т. Д., Так что есть переключатель, который вы можете увидеть в коде ниже. За исключением того, что я понял, что такие вещи, как цифровые клавиши вдоль верхнего края, обозначаются как D1, D2 и т. Д., А затем появляются такие вещи, как Add для numpad +. Кроме того, Print Screen не распознается.

Я что-то упускаю?

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

private int numKeys = 0;
private List<int> shortcutKeys = new List<int>();

private void textBoxRegionKeys_Click(object sender, EventArgs e)
{
    textBoxRegionKeys.SelectAll();
}

private void textBoxRegionKeys_KeyDown(object sender, KeyEventArgs e)
{
    // There are certain keys we want to ignore...
    if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
    {
        // We can handle this ourselves, thanks
        e.SuppressKeyPress = true;

        // Shortern what we show
        string ret = e.KeyCode.ToString();
        switch (ret)
        {
            case "ControlKey": ret = "Ctrl"; break;
            case "ShiftKey": ret = "Shift"; break;
            case "Menu": ret = "Alt"; break;
        }

        // If we haven't selected anything, we should be appending
        if (textBoxRegionKeys.SelectionLength == 0)
        {
            if (numKeys > 0)
            {
                // Does our key already exist in the list?
                if (shortcutKeys.Exists(x => x == e.KeyValue))
                {
                    return;
                }

                textBoxRegionKeys.Text += " + ";
            }
            textBoxRegionKeys.Text += ret;
            shortcutKeys.Add(e.KeyValue);
            numKeys++;
        }
        else
        {
            textBoxRegionKeys.Text = ret;
            shortcutKeys.Clear();
            shortcutKeys.Add(e.KeyValue);
            numKeys = 1;
        }
    }
}

1 Ответ

1 голос
/ 05 ноября 2010

TextBox KeyDown / KeyPress и т. Д. Будет вызываться только для клавиш, которые могут быть приняты в качестве ввода в текстовое поле (и связанные с ним модификаторы).Таким образом, вы не увидите обработанные клавиши, такие как Print Screen и т. Д. Лучший вариант, который я могу себе представить, не идеален, но вы можете переопределить ProcessKeyPreview или какой-либо другой перехватчик сообщений уровня формы, чтобы получать уведомления о ЛЮБОМ нажатии клавиши.Что-то вроде ...

protected override bool ProcessKeyPreview(ref Message m)
{
  var keyCode = (Keys)Enum.ToObject(typeof (Keys), m.WParam);

  //Insert some logic 

  return base.ProcessKeyPreview(ref m);
}

Конечно, этот метод будет вызываться всякий раз, когда ФОРМА имеет фокус, и нажата клавиша, поэтому вам придется отфильтровать, выполнив некоторую форму проверки (которая сноване идеален)

if(ReferenceEquals(ActiveControl, textBoxRegionKeys)) {}

Что, если вы будете иметь дело с такими вещами, как UserControls, будут очень ненадежными.

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

Редактировать

Немного покопался и не смог найти ничего очевидного для хороших сочетаний клавиш.Я бы просто создал карту "дружественных" названий клавиш:

private static readonly Dictionary<Keys, String> KeysMap = new Dictionary<Keys, String>
                                                             {
                                                                { Keys.D1, "1"},
                                                                { Keys.D9, "9"}
                                                             };

и сделал бы что-то вроде:

  String friendlyKeyCode;
  if (!KeysMap.TryGetValue(keyCode, out friendlyKeyCode))
    friendlyKeyCode = keyCode.ToString();

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

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