Верните фокус на ранее сфокусированный элемент управления событиями нажатия кнопки C# winforms
Я создал пользовательский элемент управления "Цифровая клавиатура", который я хочу разместить в своем приложении winform. Все кнопки имеют OnClick
событие для отправки значения в текстовое поле с фокусом в моей форме, где я разместил свой пользовательский элемент управления. Как это:
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null && focusedCtrl is TextBox)
{
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
focusedCtrl
должен быть установлен на MouseDown
событие кнопки, как это:
private void btnNum1_MouseDown(object sender, EventArgs e)
{
focusedCtrl = this.ActiveControl;
}
где this.ActiveControl
представляет активный контроль в форме.
Моя проблема в том, что кнопка всегда получает фокус, прежде чем событие обнаружит, каким был фокусный элемент управления ранее. Как определить, на каком элементе управления был фокус, до того, как кнопка получила фокус? Есть ли другое событие, которое я должен использовать? Заранее спасибо!
РЕДАКТИРОВАТЬ: Кроме того, я бы не хотел использовать GotFocus
событие в каждом текстовом поле в форме для установки focusedCtrl
поскольку это может быть утомительным и потому что я хотел бы, чтобы все кодирование моего пользовательского элемента управления находилось в самом элементе управления, а не в форме, в которой он размещен. (Я сделаю это, хотя, если нет другого практического способа сделать то, что я прошу)
4 ответа
Ваше требование довольно неразумно, вам понадобится какая-то гарантия, что ваша кнопка не будет вставлять текст в неподходящие места. Вам действительно нужно, чтобы форма сотрудничала, только она знает, какие места подходят.
Но это не невозможно, вы можете прослушивать входные события, прежде чем они будут отправлены в элемент управления с фокусом. Другими словами, запишите, какой элемент управления имеет фокус перед запуском события фокусировки. Это возможно в Winforms с интерфейсом IMessageFilter.
Добавьте новый класс в ваш проект и вставьте код, показанный ниже. Компиляция. Перетащите новый элемент управления из верхней части панели инструментов на форму, заменив существующие кнопки.
using System;
using System.Windows.Forms;
class CalculatorButton : Button, IMessageFilter {
public string Digit { get; set; }
protected override void OnClick(EventArgs e) {
var box = lastFocused as TextBoxBase;
if (box != null) {
box.AppendText(this.Digit);
box.SelectionStart = box.Text.Length;
box.Focus();
}
base.OnClick(e);
}
protected override void OnHandleCreated(EventArgs e) {
if (!this.DesignMode) Application.AddMessageFilter(this);
base.OnHandleCreated(e);
}
protected override void OnHandleDestroyed(EventArgs e) {
Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
}
bool IMessageFilter.PreFilterMessage(ref Message m) {
var focused = this.FindForm().ActiveControl;
if (focused != null && focused.GetType() != this.GetType()) lastFocused = focused;
return false;
}
private Control lastFocused;
}
У вас есть событие под названием lostFocus, которое вы можете использовать
button1.LostFocus +=new EventHandler(dataGridView1_LostFocus);
и в случае:
Control lastFocused;
void dataGridView1_LostFocus(object sender, EventArgs e)
{
lastFocused = sender as Control;
}
таким образом, вы всегда можете знать, что такое контроль, который был сфокусирован ранее
исправьте меня, если я ошибаюсь, но вы делаете это для SendKeys.Send("1");
знать, какой textBox
нужно получить номер. для этого вы можете использовать GotFocus
событие и зарегистрировать только textBox
с этим.
Вы также можете делать то, что делает Windows, и использовать только одно текстовое поле, как здесь:
если это соответствует вашим потребностям
Control focusedCtrl;
//Enter event handler for all your TextBoxes
private void TextBoxesEnter(object sender, EventArgs e){
focusedCtrl = sender as TextBox;
}
//Click event handler for your btnNum1
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null){
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
Как насчет использования этого с параметром forward = false?
Control.SelectNextControl Method
Вы, вероятно, назвали бы это своим "пользовательским управлением с помощью цифровой клавиатуры".