允许某些键盘敲击/事件用于禁用控制

时间:2014-01-03 23:50:01

标签: c# controls keyboard-events disabled-control

我有一个禁用控件。我仍然希望按键和按键事件被触发,因为我想知道某个键。

当我测试它时,似乎没有任何控件的事件被触发。关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

缺乏互动是禁用控制的基本理念,它正在按预期工作。

您可以使用Form的KeyPreview属性,然后从Form事件启动已禁用控件的事件处理程序。

通常,有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,通过Form本身进行主控制,在名为的控件上显示带有“help_”作为helpBox的控件。

        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期间发生),控件将更改其位置。 / p>

4 - 自己画吧!操纵控件并不总是最佳解决方案,相反,您可能只想在控件上绘制一些东西。

private void Form1_KeyDown(object sender,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));
        }
    }

注意:每个Control都有Tag属性,因为它是对象类型,您可以在其中存储任何您想要的内容。这使它成为通用定制属性。如果你想知道这个属性的含义:它没有意义,它是用户定义的。