Клавиша Enter не закрывает форму, если фокус находится на кнопке, которая не является кнопкой AcceptButton

#c# #winforms #dialogresult #acceptbutton

#c# #winforms #dialogresult #acceptbutton

Вопрос:

У меня есть модальная форма с тремя кнопками, A B и C.

Кроме того, у меня есть две кнопки: OK и Cancel . OK DialogResult Для свойства кнопки установлено значение DialogResult.OK и Cancel кнопка DialogResult.Cancel .
Форма AcceptButton и CancelButton свойства устанавливаются на эти кнопки.

В настоящее время форма закрывается, когда я нажимаю ESC клавишу, но если я нажимаю ENTER клавишу, когда одна из других кнопок (A, B, C) является активным элементом управления, форма не закрывается. Как я могу это преодолеть?

У меня есть два варианта:

  1. Ввод всегда будет закрывать форму (выберите сфокусированную кнопку, а затем закройте ее),

  2. Первое нажатие клавиши Enter выделит сфокусированную кнопку, а второе ENTER нажатие закроет форму. Проблема в том, что, возможно, кнопка A была выбрана, но пользователь может перейти по кнопке B или C с помощью клавиш со стрелками.

Я не могу установить a DialogResult.OK для других кнопок, потому что — в этом случае — обычный щелчок также закроет форму, и у меня нет способа определить, было ли вызвано событие из-за события щелчка или ENTER клавиши…

Комментарии:

1. Покажите нам код, который вы написали.

Ответ №1:

Если вы хотите активировать кнопку по умолчанию — кнопку, которая установлена в качестве кнопки AcceptButton формы, — когда фокус находится на другой кнопке, но не на другом элементе управления в виде текстового поля, который может захотеть принять Enterключ, вы можете переопределить ProcessCmdKey (поскольку нажатие Enterклавиши не вызывает KeyDown событие, и текстовое поле Click не отображается).событие вызывается перед KeyUp событием), проверьте, имеет ли ActiveControl тип Button (или другой тип элементов управления, которые вы хотите вести себя так же) и установите значение ActiveControl your AcceptButton .

EnterКлавиша передается AcceptButton , и диалоговое окно закрывается, возвращаясь DialogResult.OK (поскольку вы уже установили значение кнопки DialogResult ):

Примечание: это предполагает, что элемент управления контейнером тот же.

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Enter) {
        if (ActiveControl.GetType() == typeof(Button) amp;amp;
            ActiveControl != AcceptButton) {
            ActiveControl = AcceptButton as Button;
        }
    }
    return base.ProcessCmdKey(ref msg, keyData);
}
  

В случае, если вы просто хотите изменить ActiveControl , установив фокус на AcceptButton — так что пользователю необходимо Enterдважды нажать клавишу для подтверждения, вернитесь true после того, как вы изменили ActiveControl , чтобы сообщить, что ввод был обработан:

 // [...]
if (keyData == Keys.Enter) {
    if (...) {
        ActiveControl = AcceptButton as Button;
        return true;
    }
}
return base.ProcessCmdKey(ref msg, keyData);