1.我现在有个曲线图,想用键盘的上、下、左、右键通过移动去读取每个点的坐标,类似现在的股票软件;2.于是,我就用picturebox控件画了这样的曲线图,可惜picturebox没有键盘事件;3.上网查了资料,有的说去重载键盘事件,可发现重载后,其他控件的键盘事件都需要修改或者就不可用;也有的说把picturebox放到另外的可用键盘事件的控件上,可发现除了类似panel这样的容器控件可盛放其他控件外,其他控件都放不了,而panel同样也没有键盘事件;4.是否做这样的功能,不是用picturebox控件的,那么用什么控件可以呢?或者用其他什么方法可实现这样的功能呢?
  
O(∩_∩)O谢谢!

解决方案 »

  1.   

    1.在panel上重画image,然后就可以用键盘事件了
    2.不要用picturebox控件,非常不好用,制约你的开发
      

  2.   

    把Form的KeyPreview高为true,就可以从Form_KeyPress/KeyDown/KeyUp截获按键了。
      

  3.   


    可是panel没用键盘事件啊。
      

  4.   


    是可以截获按键,可是这只局限于有键盘事件的控件,像panel/picturebox这样本身就没键盘事件的,如何截获?
      

  5.   

    在FORM内处理键盘事件有什么问题?
      

  6.   


    没问题。但在FORM内加个比如pixturebox,就有问题。
      

  7.   


    你能否能告诉我,如何截获picturebox上的键盘事件?
      

  8.   

    我估计你是没明白重载键盘事件是啥意思吧。
    直接把下面这个函数写在
    public class form1:form 

          这里
    }
    就行了,你想处理什么键,直接处理就好了。protected override void ProcessCmdKey(ref Message message, Keys keyData) 

        switch(keyData) 
        { 
            case Keys.Up: 
                    // ..... 
                break; 
        } 
    } 处理完想让其他事件继续处理的话,就在函数最后加一句。
    base.ProcessCmdKey(ref msg, keyData);
      

  9.   

    思路有问题,picturebox之类的没有焦点,它怎么知道你是不是在它内部按键的,在form的按键事件里处理就是了
      

  10.   


    “在form的按键事件里处理”……picturebox我也是加到一个form里的,一个form里有很多控件,你说的“在form的按键事件里处理”太笼统了吧。
    讨教你的思路!
      

  11.   

    在form的onkeydown事件里处理啊,你在picturebox上按下键盘,form里面的事件不就影响了么? 
      

  12.   

    你可以考虑直接在Form里面画图,然后抓Form的事件,
    如果你要用Picture,当事件触发后,你要让事件上升就可以了
    如果你也可以在最底层使用抓事件,使用API的消息勾子也可以
      

  13.   


    我试过你这个方法,比如我写了一个form.keydown事件,触发之后,想在picturebox指定的位置画条线,可实践后,picturebox上并没出现这条线。(form.keypreview已设为true)
      

  14.   


    哥,你说的两个“如果”好飘忽啊,莫非我OUT了!
      

  15.   

    新创建一个用户控件,
    既可以实现画图功能,同时利用控件的Key事件。
      

  16.   

    写了一个简单的控件。public partial class NewPanel : UserControl
        {
            int Oldx, Oldy, Newx, Newy;
            public NewPanel()
            {
                InitializeComponent();
                Oldx = this.Width / 2;
                Oldy = this.Height / 2;
                Newx = Oldx;
                Newy = Oldy;
            }        private void NewPanel_Paint(object sender, PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                g.DrawRectangle(new Pen(Color.Green), new Rectangle(0, 0, this.Width - 1, this.Height - 1));
                g.DrawLine(new Pen(Color.Red, 20), new Point(Oldx, Oldy), new Point(Newx, Newy));
                Oldx = Newx;
                Oldy = Newy;
                
            }        private void NewPanel_KeyUp(object sender, KeyEventArgs e)
            {
                bool bDraw = false;
                if (e.KeyCode == Keys.Left)
                {
                    Newx = Oldx - 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Right)
                {
                    Newx = Oldx + 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Up)
                {
                    Newy = Oldy - 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Down)
                {
                    Newy = Oldy + 1;
                    bDraw = true;
                }
                if(bDraw == true) this.Invalidate();
            }
        }
      

  17.   


    我刚才又试了下,没出现是因为form里的控件把画出来的线覆盖掉了。也就是说,这个方法虽然实现了键盘事件,但并没实现我上面的功能。
      

  18.   

    你可以考虑直接在Form里面画图,然后抓Form的事件, 
    如果你要用Picture,当事件触发后,你要让事件上升就可以了 
    如果你也可以在最底层使用抓事件,使用API的消息勾子也可以另外:public partial class NewPanel : UserControl
        {
            int Oldx, Oldy, Newx, Newy;
            public NewPanel()
            {
                InitializeComponent();
                Oldx = this.Width / 2;
                Oldy = this.Height / 2;
                Newx = Oldx;
                Newy = Oldy;
            }        private void NewPanel_Paint(object sender, PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                g.DrawRectangle(new Pen(Color.Green), new Rectangle(0, 0, this.Width - 1, this.Height - 1));
                g.DrawLine(new Pen(Color.Red, 20), new Point(Oldx, Oldy), new Point(Newx, Newy));
                Oldx = Newx;
                Oldy = Newy;
                
            }        private void NewPanel_KeyUp(object sender, KeyEventArgs e)
            {
                bool bDraw = false;
                if (e.KeyCode == Keys.Left)
                {
                    Newx = Oldx - 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Right)
                {
                    Newx = Oldx + 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Up)
                {
                    Newy = Oldy - 1;
                    bDraw = true;
                }
                else if (e.KeyCode == Keys.Down)
                {
                    Newy = Oldy + 1;
                    bDraw = true;
                }
                if(bDraw == true) this.Invalidate();
            }
        }
      

  19.   

    各位,我LV一LV,貌似有思路了。有关注的同学,敬请继续关注,我们今天一定要把这个问题消灭掉。
      

  20.   

    那就给你写一段
    上-圆弧
    下-圆
    左-直线
    右-方框
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;namespace WindowsApplication247
    {
        public partial class Form1 : Form
        {
            PictureBox PB = new PictureBox();        public Form1()
            {
                InitializeComponent();            PB.Parent = this;
                PB.BackColor = Color.Black;            this.KeyDown += new KeyEventHandler(Form1_KeyDown);
            }        void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                Bitmap Bmp = new Bitmap(PB.ClientRectangle.Width, PB.ClientRectangle.Height);            using (Graphics G = Graphics.FromImage(Bmp))
                {
                    G.Clear(Color.Black);                switch (e.KeyCode)
                    {
                        case Keys.Up: G.DrawArc(Pens.Red, new Rectangle(0, 0, 50, 50), 0, 300); break;
                        case Keys.Down: G.DrawEllipse(Pens.Green, new Rectangle(0, 0, 50, 50)); break;
                        case Keys.Left: G.DrawLine(Pens.Blue, new Point(0, 0), new Point(50, 50)); break;
                        case Keys.Right: G.DrawRectangle(Pens.Yellow, new Rectangle(0, 0, 50, 50)); break;
                    }
                }            PB.Image = Bmp;
                GC.Collect();
            }
        }
    }
      

  21.   


    哪里有制约?画在bitmap上再显示出来不是和画其他地方一样么,而且还不用担心刷新问题,
      

  22.   


    不好使的原因是,你处理完以后,如果你想让其他功能接受到键消息,就要继续把这个消息往下传递才行。。protected override void ProcessCmdKey(ref Message message, Keys keyData) 

        switch(keyData) 
        { 
            case Keys.Up: 
                    // ..... 
                break; 
        } 
        base.ProcessCmdKey(ref msg, keyData);
      

  23.   

    spade24好,能否把你写的代码给我学习好吗,多谢!我发站内消息给你了
      

  24.   

    太有用了!感谢大牛解决了我的困惑。自从在窗口加了windows media player控件之后,KeyPress/KeyDown/KeyUp 这件事件通通都没有处理。
    原来是KeyPreview呀~