处理表单中的KeyDown事件

时间:2016-06-13 14:43:25

标签: c# winforms keydown arrow-keys

我刚刚发现我们无法直接将KeyDown事件与PictureBox一起使用。所以我必须改变我的策略。

我决定将Keydown事件添加到实际表单中:

private void FullColourPaletteForm_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Left:
            {
                MessageBox.Show("Left");
                e.Handled = true;
                return;
            }
    }

}

不执行。当我按左侧允许时,我看不到任何消息框。相反(并且正确地说)它只是将cusor从控制转移到控制。

Colour Palette

我希望能够通过截取图片框内的方向键来模仿某种颜色的光标支持。

我不确定前进的最佳方式。我不想打破在控件之间移动的标准对话功能,但我现在想要包含检测键的suipport,这样我就可以添加我的代码来移动我的颜色块。

可以吗?不知道为什么我的活动不会在表格中被触发。

我看到了question。所以我尝试设置我的表单 KeyPreview 属性。没有快乐。我也看了ProcessCmdKey,但这对于手头的问题似乎并不合适。

更新

如果我尝试在评论中遵循这个想法并创建一个SelectablePictureBox控件,它看起来像这样:

With focus

我有两个问题。我似乎还无法解决如何处理我的pictureBox对象本身的keydown事件。我不愿意手动将任何处理程序添加到设计器文件中,以免我的更改丢失。

此外,当使用光标键对表单进行一般控制时,它似乎不知道这个控件。

1 个答案:

答案 0 :(得分:2)

如果您想在表单级别处理箭头键,可以通过以下方式覆盖表单ProcessCmdKey函数:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Left)
    {
        MessageBox.Show("Left");
        return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

但总的来说,创建像this这样的自定义绘制可选控件更好,而不是将这种逻辑放在表单级别。你的控制应该包含这样的逻辑。

注意

  

OP:我刚刚发现我们无法直接使用KeyDown事件   使用PictureBox

Hanscomments所述,PictureBox控件不可选,默认情况下无法对焦,您无法处理控件的键盘事件。

但你可以强制它可以选择并以这种方式支持键盘事件:

using System;
using System.Reflection;
using System.Windows.Forms;
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        this.pictureBox1.SetStyle(ControlStyles.Selectable, true);
        this.pictureBox1.SetStyle(ControlStyles.UserMouse, true);
        this.pictureBox1.PreviewKeyDown +=
            new PreviewKeyDownEventHandler(pictureBox1_PreviewKeyDown);
    }
    void pictureBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyData == Keys.Left)
            MessageBox.Show("Left");
    }
}
public static class Extensions
{
    public static void SetStyle(this Control control, ControlStyles flags, bool value)
    {
        Type type = control.GetType();
        BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
        MethodInfo method = type.GetMethod("SetStyle", bindingFlags);
        if (method != null)
        {
            object[] param = { flags, value };
            method.Invoke(control, param);
        }
    }
}

至少知道这种方法是一种黑客攻击,你可以重用扩展方法来启用或禁用控件上的某些样式。