猿问

如何动态创建移动面板

我目前正在 x 轴上创建一个由按钮触发的移动面板,winform它工作得很好,但现在我想在每次单击按钮时添加多个面板。问题是我通过工具箱创建了面板并将其附加在 a 上timer_tick event,我相信这只能完成一次,所以我的计划是创建一个动态面板和计时器不知道它是否是正确的方法。


这是我的代码


   private void button2_Click(object sender, EventArgs e)

     {

            start();

     } 


    private void start(){


        timer1.Enabled = true;

    }


    private void timer1_Tick(object sender, EventArgs e )

    {

        panel_1.BackColor = Color.Green;

        int x = panel_1.Location.X;

        int y = panel_1.Location.Y;


        panel_1.Location = new Point(x + 25, y);

        xy_text.Text = x + ","+ y;

        if (x > this.Width)

        {

            timer1.Stop();

        }

    }


www说
浏览 111回答 3
3回答

月关宝盒

    private List<Panel> _panels = new List<Panel>(); //class level list to track the panels    private void button2_Click(object sender, EventArgs e)    {        //create a new panel when the button is clicked        var p = new Panel();        p.Size = new Size(10, 10);        p.Location = new Point(10, DateTime.Now.Second * (this.Height / 60)); //"random" Y so they don't pile up        p.BackColor = Color.Green;        this.Controls.Add(p);                           //add panel to form        _panels.Add(p);                                 //add panel to list        timer1.Enabled = true;                          //animate    }    private void timer1_Tick(object sender, EventArgs e)    {        for (int i = _panels.Count - 1; i >= 0; i--)    //use a backwards int indexed loop because we are potentially removing items from the list.         {                                               //Working backwards is the easiest way to not have to fiddle the index upon removal            var p = _panels[i];                         //temp reference to a panel in the list, not related to 'var p' in the button click            p.Left += 25;                               //move it            if (p.Left > this.Width)                    //panel that is off screen?                _panels.RemoveAt(i);                    //stop moving it then        }        if (_panels.Count == 0)                         //no more panels to move?            timer1.Stop();                              //stop the timer    }this.Controls如果您不再使用不可见的面板,您应该考虑实现一些逻辑,将其从集合中删除。

Qyouu

这是我写的一个简单的例子,这里我使用 1 个计时器来处理所有面板,如果你想让它更平滑,使运动增量更小(从 25 到更低)并增加计时器的滴答率,你也可以尝试单独为每个面板使用一个计时器,但在我看来这有点过分了。编辑:如果您想要真正精确的定位和动画,则需要使用更精确的双精度移动,并舍入为动画本身的整数,请使用 DateTime.Now 来非常精确地确定给定时间内行驶的距离,计时器不会t 确定距离,它只更新位置:public partial class MainForm : Form{&nbsp; &nbsp; // X directional speed in pixels per second&nbsp; &nbsp; const int XSpeed = 400;&nbsp; &nbsp; private List<AnimationPanel> _panels = new List<AnimationPanel>();&nbsp; &nbsp; public MainForm()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; }&nbsp; &nbsp; private void OnButtonStartClick(object sender, System.EventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; AnimationPanel newPanel = new AnimationPanel&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Bounds = new Rectangle(10, 10, 50, 50),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BorderStyle = BorderStyle.FixedSingle,&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; _panels.Add(newPanel);&nbsp; &nbsp; &nbsp; &nbsp; Controls.Add(newPanel);&nbsp; &nbsp; &nbsp; &nbsp; newPanel.StartBounds = newPanel.Bounds;&nbsp; &nbsp; &nbsp; &nbsp; newPanel.StartTime = DateTime.Now;&nbsp; &nbsp; &nbsp; &nbsp; _timer.Enabled = true;&nbsp; &nbsp; }&nbsp; &nbsp; private void OnTimerTick(object sender, System.EventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = _panels.Count - 1; i >= 0; i--)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AnimationPanel currentPanel = _panels[i];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DateTime startTime = currentPanel.StartTime;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int xDelta = (int)Math.Round((DateTime.Now - startTime).TotalSeconds * XSpeed, 0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point newLocation = new Point(currentPanel.StartBounds.X + xDelta, currentPanel.StartBounds.Y);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Check before or after collision (in this example before replacing the AnimationPanel)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (newLocation.X > this.Width)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // I chose to remove after it reaches the edge, do whatever you want&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _panels.RemoveAt(i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Controls.Remove(currentPanel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentPanel.Location = newLocation;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (_panels.Count == 0)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _timer.Enabled = false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private class AnimationPanel : Panel&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public Rectangle StartBounds { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public DateTime StartTime { get; set; }&nbsp; &nbsp; }}

慕妹3146593

您可以使用如下代码创建面板:&nbsp; &nbsp; &nbsp; &nbsp; // init properties&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; var newPanel = new Panel&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name="Panel1",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BackColor = Color.Green,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Location = new Point(0, 0), // set the starting point&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Width = 100, Height = 100&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; Controls.Add(newPanel);
随时随地看视频慕课网APP
我要回答