Обработка необработанного ключа ввода с #

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

Итак, когда ввод нажата в TextBox или DateTimePicker, я хочу обработать его с помощью формы (без звука ошибки), но если он нажат, например, в DataGridView, я хочу, чтобы он обрабатывался так, как DataGridView делает по умолчанию .

OnKeyUp решает мою проблему с обработкой только необработанных нажатий клавиш (e.Handled) и ProcessCmdKey (this) решает проблему со звуком, но ни то, ни другое не решает обоих.

Какие-либо предложения?


person Damir    schedule 01.10.2010    source источник


Ответы (1)


Престижность за очень интересный вопрос. К сожалению, я не могу найти глобального обработчика событий для всех нажатий клавиш, кроме переопределения ProcessCmdKey в основной форме на эта статья. Единственная проблема с этим методом заключается в том, что аргументы, передаваемые делегату обработчика события, не определяют, какой элемент управления создает событие :(

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

Код:

private void Form1_Load(object sender, EventArgs e)
{
    AssignHandler(this);
}

protected void HandleKeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == (char)Keys.Enter && (sender != this.textBoxToIgnore || sender ! this.gridViewToIgnore))
    {
        PlaySound();  // your error sound function
        e.Handled = true;
    }
}

public void AssignHandler(Control c)
{
    c.KeyPress += new KeyPressEventHandler(HandleKeyPress);
    foreach (Control child in c.Controls)
    {
        AssignHandler(child);
    }
}
person regex    schedule 01.10.2010
comment
Параметр Msg для ProcessCmdKey содержит HWND целевого элемента управления (окна). Вы можете использовать Control.FromHandle для получения управляемого объекта Control. - person Tergiver; 02.10.2010
comment
Я не знал, что обработка KeyPress предотвращает звук ошибки. Я попробовал это с KeyUp и почему-то предположил, что он не будет работать и с KeyPress. Однако, чтобы поймать ключевые события из формы, вам не нужно делать все это, просто установите для свойства KeyPreview формы значение true и обработайте ее ключевые события. - person Damir; 02.10.2010
comment
Кроме того, чтобы не указывать явно, какие элементы управления обрабатывают или не обрабатывают ввод, достаточно добавить &&! E.Handled в операторе if - person Damir; 02.10.2010
comment
@Damir, похоже Tergiver (см. Комментарии к моему посту) может быть более точным, чем я. Похоже, что параметр msg, предоставленный обработчику ProcessCmdKey, содержит дескриптор окна для окна (элемент управления .NET), отправившего сообщение. вы должны иметь возможность использовать этот метод, а не назначать обработчик каждому элементу управления. - person regex; 05.10.2010
comment
Да, но ProcessCmdKey перехватывает нажатие клавиши на уровне формы и никогда не попадает в элементы управления, которые могли бы его обработать. - person Damir; 11.10.2010