Разрешить определенные нажатия клавиш / события для отключенного управления
У меня отключен контроль. Я все еще хочу, чтобы события нажатия клавиш и запускались, потому что я хотел бы знать об определенном ключе.
Когда я проверил это, кажется, что ни одно из событий элемента управления не запускается. Есть идеи как обойти это?
1 ответ
Недостаток взаимодействия - основная идея отключения контроля, она работает так, как задумано.
Вы можете использовать свойство KeyPreview формы, а затем запускать обработчики событий отключенного элемента управления из событий формы.
Как обычно, есть n+1 способов достичь того, что вы ищете. Поэтому я представлю только некоторые из них.
1 - манипулировать фокусом. Несмотря на простоту реализации, он также нестабилен, так как пользователь может манипулировать фокусом.
private void button_KeyDown(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Add(helpBox);
((Control)sender).Focus(); // Set focus back to control so its KeyUp will be called
}
private void button_KeyUp(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Remove(helpBox);
}
2 - Несколько вызовов одного и того же обработчика событий. Да, это возможно. Немного сложнее и может зависеть от класса управления helpBox и / или его событий. Возможные проблемы могут включать многократный обработчик событий, однако представленный код безопасен для использования, даже если такая ситуация произойдет.
private void button_KeyDown(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Add(helpBox);
helpBox.KeyUp += button_KeyUp; //This will add KeyUp of our hosting button to hosted control, which means that said KeyUp handler can be raised by both helpBox and button
}
private void button_KeyUp(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Remove(helpBox);
helpBox.KeyUp -= button1_KeyUp; // to avoid unnecessary calls event handler can be easily "subtracted" from helpBox
}
3 - Главный элемент управления самой формой с использованием KeyPreview, установленного в true, показывает элементы управления с "help_" в качестве справочных ящиков на именованных элементах управления.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
foreach (Control c in this.Controls)
{
string hName = "help_" + c.Name;
Control[] help = this.Controls.Find(hName, true);
if (help.Length>0)
{
c.Controls.Add(help[0]);
}
}
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
foreach (Control c in this.Controls)
{
string hName = "help_" + c.Name;
Control[] help = c.Controls.Find(hName, true);
if (help.Length > 0)
{
c.Controls.Remove(help[0]);
}
}
}
}
Примечание. Положение элемента управления на экране зависит от его родительской позиции (относительно верхнего левого угла родительского элемента), другими словами, путем изменения родительского элемента управления (что происходит во время Controls.Add) элемент управления изменит свою позицию.
4 - Нарисуй это сам! Управление элементами управления не всегда является лучшим решением, вместо этого вы можете просто нарисовать что-то на элементе управления.
private void Form1_KeyDown (отправитель объекта, KeyEventArgs e) { button1.Tag = true; button1.Update(); }
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
button1.Tag = false;
button1.Update();
}
// there is no reason to re-draw it constantly, Paint event will be fired when needed
private void button1_Paint(object sender, PaintEventArgs e)
{
// remember that all Tag's start as null
if (((Control)sender).Tag != null && (bool)((Control)sender).Tag == true)
{
// and when needed just paint on control drawing area (also known as Canvas)
e.Graphics.FillRectangle(Brushes.Red, 0, 0, 100, 100);
e.Graphics.DrawString("Foo!", ((Control)sender).Font, Brushes.Beige, new PointF(5, 5));
}
}
Примечание. Каждый элемент управления имеет свойство Tag, поскольку он имеет тип объекта, в котором вы можете хранить все, что захотите. Что делает его универсальным пользовательским свойством. Если вас интересует значение этого свойства: оно не имеет смысла, оно определяется пользователем.