如何在 c# 中在 keysDown 事件上向上/向下移动面板

本文关键字:移动 事件 中在 keysDown | 更新日期: 2024-11-07 17:38:26

我有 4 个面板,具有相同的 Y 和不同的 X,它们是在程序开始时在图片框上创建的。当我单击面板时,它会设置焦点并准备好获取 keysDown 事件,因此,如果我单击向上箭头键,面板将向上移动。

这是代码:

public partial class FormView : Form
{
    List<CircleButton> myPanels = new List<CircleButton>(); // array of panels CircleButton
    Point[] arrayPoints_milestones; // array of X,Y
    int index;
    public FormView()
    {
        InitializeComponent();
        arrayPoints_milestones = new Point[4];
        for (int i = 0; i < 4; i++ )
        {
            arrayPoints_milestones[i] = new Point { X = 20, Y = 20 };
        }
        test();
    }
    protected void panel_Click(object sender, EventArgs e)
    {
        myPanels[index].PreviewKeyDown -= new PreviewKeyDownEventHandler(panel_KeyDown);
        CircleButton panel = sender as CircleButton;
        index = (int)panel.Tag;
        myPanels[index].Focus(); //panel.Focus();            
        myPanels[index].PreviewKeyDown += new PreviewKeyDownEventHandler(panel_KeyDown);
    }
    private void panel_KeyDown(object sender, PreviewKeyDownEventArgs e)
    {         
        if (e.KeyCode == Keys.Up)
        {
            myPanels[index].Centre = new Point(myPanels[index].Centre.X, myPanels[index].Centre.Y - 10);
            MessageBox.Show("" + myPanels[index].Centre.Y);
            Invalidate();
        }
        if (e.KeyCode == Keys.Down)
        {
            myPanels[index].Centre = new Point(myPanels[index].Centre.X, myPanels[index].Centre.Y + 10);
            MessageBox.Show("" + myPanels[index].Centre.Y);
            Invalidate();                
        }    
    }
    private void test()
    {
        //for (int i = 0; i < 4; i++)
        int i=0;
        foreach(var value in arrayPoints_milestones)
        {
            CircleButton panel = new CircleButton();
            panel.Tag = i;
            panel.Centre = new Point(arrayPoints_milestones[i].X + i * 10, arrayPoints_milestones[i].Y);
            panel.Radius = 10;
            panel.BackColor = Color.Red;
            panel.Message = "Index: " + panel.Tag.ToString();
            myPanels.Add(panel); // qui aggiungo il pannello alla lista di pannelli myPanels 
            pictureBox1.Controls.Add(myPanels[i]);
            myPanels[i].Click += new EventHandler(panel_Click);
            i++;
        }
    }
}

这是自定义面板类:

public class CircleButton : Panel
{
    //Properties to draw circle
    float radius;
    public float Radius
    {
        get { return radius; }
        set
        {
            radius = value;
            this.Size = new Size((int)Radius, (int)Radius);
        }
    }
    public string Name
    {
        get;
        set;
    }
    Point centre;
    public Point Centre
    {
        get { return centre; }
        set
        {
            centre = value;
            this.Location = Centre;
        }
    }
    public string Message { get; set; }
    public CircleButton()
    {
        //Default Values
        Name = "panel_base";
        this.BackColor = Color.Black;
        Radius = 1;
        Centre = new Point(0, 0);
        this.DoubleBuffered = true;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        //Defines a graphic path and set it as the panel's region
        //For custom region use different path's
        if (centre != null)
        {
            GraphicsPath path = new GraphicsPath();
            path.AddEllipse(0, 0, radius, radius);
            this.Region = new Region(path);
            path.Dispose();
        }
    }        
}

如何在 c# 中在 keysDown 事件上向上/向下移动面板

每次单击面板时,都会添加一个PreviewKeyDownEventHandler - 因此 3 次单击将触发 3 个(不同的)具有相同调用目标的事件处理程序,每个事件处理程序将面板向上/向下移动 10 个像素:

protected void panel_Click(object sender, EventArgs e) {
    CircleButton panel = sender as CircleButton;
    index = (int)panel.Tag;
    myPanels[index].Focus(); //panel.Focus();
    myPanels[index].PreviewKeyDown += new PreviewKeyDownEventHandler(panel_KeyDown);
}


更新了窗体视图的代码:

public partial class FormView : Form {
    List<CircleButton> myPanels = new List<CircleButton>(); // local use only in my example
    Point[] arrayPoints_milestones; //not needed anymore
    int index; //not needed anymore
    public FormView() {
        InitializeComponent();
        this.Load += FormView_Load;
    }
    void FormView_Load(object sender, EventArgs args) {
        Point panelOffset = new Point(20, 20);
        for (int i = 0; i < 4; i++) {
            var panel = new CircleButton() {
                Name = "panel" + i, //Attention! You have hidden the property "Name" in "Control" with a re-declaration in "CircleButton"
                Tag = i, //not needed anymore, right?
                Centre = new Point(panelOffset.X + i * 10, panelOffset.Y),
                Radius = 10,
                BackColor = Color.Red,
                Message = "Index: " + i.ToString(),
            };
            panel.Click += (s, e) => {
                panel.Focus();
            };
            panel.PreviewKeyDown += (s, e) => {
                if(e.KeyCode == Keys.Up) {
                    Point centre = panel.Centre; //copy value
                    centre.Y -= 10;
                    panel.Centre = centre; //assign modified copy
                    Invalidate();
                }
                if(e.KeyCode == Keys.Down) {
                    Point centre = panel.Centre; //copy value
                    centre.Y += 10;
                    panel.Centre = centre; //assign modified copy
                    Invalidate();
                }
            };
            myPanels.Add(panel);
            pictureBox1.Controls.Add(panel);
        }
    }
}