Handling arrow keys in a Form

前端 未结 1 1253
自闭症患者
自闭症患者 2021-01-24 15:39

I have just found out that we can\'t use the KeyDown event directly with a PictureBox. So I have to change my strategy.

I decided to add the

相关标签:
1条回答
  • 2021-01-24 15:59

    If you want to handle arrow keys at form level, you can override the form's ProcessCmdKey function this way:

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

    But in general it's better to create a custom paint selectable control like this rather than putting such logic at form level. Your control should contain such logic.


    Note

    OP: I have just found out that we can't use the KeyDown event directly with a PictureBox

    As mentioned by Hans in comments, the PictureBox control is not selectable and can not be focused by default and you can not handle keyboard events for the control.

    But you can force it to be selectable and support keyboard events this way:

    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);
            }
        }
    }
    

    At least knowing this approach as a hack you can reuse the extension method to enable or disable some styles on controls in future.

    0 讨论(0)
提交回复
热议问题