Обработка некоторых клавиш, когда текстовое поле сфокусировано - PullRequest
0 голосов
/ 27 октября 2019

Итак, по-видимому, у меня возникли некоторые проблемы при обработке клавиш, таких как F10 или F11.

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

private void checkKeys(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F10)
            {
                buyerName.Focus();
            }
            else if (e.KeyCode == Keys.F11)
            {
                discount.Focus();
            }
        }

Но, если я помещу это в отдельное текстовое поле, это мне немного мешает. Есть ли способ прослушивания ключа в глобальном userControl или textbox?

Редактировать: вот моя структура, которую я хочу спросить:

Form-
    |-User Control
     |-TextBox

Редактировать 2: вот некоторые изображения могут помочь img

Ответы [ 3 ]

1 голос
/ 27 октября 2019

Чтобы использовать глобальный слушатель клавиатуры в Winforms, вам просто нужно добавить обработчик к действию KeyUp для самой главной формы:

private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.F10)
        {
            textBox1.Focus();
            e.Handled = true; //To use F10, you need to set the handled state to true
        } else if (e.KeyCode == Keys.F11)
        {
            textBox2.Focus();
        }
    }

Затем убедитесь, что свойство KeyPreview в главной форме установленок Истине. enter image description here

Проблема с зависанием приложения при нажатии клавиши F10 вызвана тем, что оно ожидает другого последовательного действия. Чтобы обойти это, просто установите свойство Handled на keyevent в TRUE. Это освобождает неразрешенное событие.

Это весь мой класс формы, с рефакторингом для использования вспомогательного метода, как вы ссылаетесь. Это отлично работает. Но вы должны убедиться, что свойство KeyPreview в вашей форме имеет значение True, если только ваши нажатия клавиш не будут сопоставлены с вашими обработчиками событий.

namespace KeyTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            CheckKeys(e);
        }

        private void CheckKeys(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F10)
            {
                textBox1.Focus();
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.F11)
            {
                textBox2.Focus();
                e.Handled = true;
            }
        }
    }
}

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

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public void HandleKeys(KeyEventArgs e)
    {
        if (e.KeyCode == Keys.F10)
        {
            textBox1.Focus();
            e.Handled = true;
        }
        else if (e.KeyCode == Keys.F11)
        {
            textBox2.Focus();
            e.Handled = true;
        }
    }
}

Затем в главной форме:

public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            CheckKeys(e);
        }

        private void CheckKeys(KeyEventArgs e)
        {
            uc1.HandleKeys(e); //Instance method on your user control.
        }
    }

Это тогда работает как задумано.

Как указано в одном из комментариев, лучшим способом было бы переопределить метод ProcessCmdKey в базовом классе Form. Это будет сделано так:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        userControl11.HandleKeys(keyData); // method on the userControl to handle the key code.
        base.ProcessCmdKey(ref msg, keyData);
        return true;
    }

}

Обработчик в UserControl остается более или менее таким же:

public void HandleKeys(Keys keys)
    {
        if (keys == Keys.F10)
        {
            nameTB.Focus();
        } else if (keys == Keys.F11)
        {
            emailTB.Focus();
        }
    }

Если это более правильный способ сделать это, яне уверен в. Они оба, безусловно, достигают одного и того же результата. В документации показан первый метод обработки событий клавиатуры на уровне формы: Как обрабатывать ввод с клавиатуры

Но здесь говорится, что метод ProcessCmdKey предназначен для дополнительной обработки сочетаний клавиш и MDI. accellerators. ProcessCmdKey

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

0 голосов
/ 28 октября 2019

Спасибо @Espen и @ reza-aghaei за обработку ключей в основной форме. К сожалению, мне так и не удалось найти способ сфокусироваться на обозначенном текстовом поле внутри UserControl. Тем не менее, я использую грязный метод, который довольно дурацкий и неэффективный, ища дочерний элемент управления у его родителя

//MainForm.cs
if(yourUserControl.Name)//Do some check for targeted userControl, if null can cause NullReferenceException
{
   if (e.KeyCode == Keys.F10)
   {
     this.Controls.Find("textboxName", true).First().Focus();
     e.Handled = true;
   }
}

0 голосов
/ 27 октября 2019

Вы можете подключиться к событию KeyUp вашей формы.

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

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