如何使用点类和计时器工具在窗体中连续地将winforms工具向右再向左移动?

pkbketx9  于 2022-11-17  发布在  其他
关注(0)|答案(2)|浏览(142)

此代码的目的是使用2个计时器工具和Point类,将标题(标签)首先向右移动,直到它到达窗体X轴上的第600个像素,然后向左移动,直到它到达窗体X轴上的第27个像素。一个计时器用于向右移动,另一个计时器用于向左移动。它们应该通过一个接一个地连续打开和关闭来工作,但是它没有工作。
标签卡在第600个X位置,无法移回原来位置。
计时器间隔是100,所以它以一个体面的速度移动,让我们看到它移动。

namespace AlanCevreHesabiUygulamasi
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            if (label11Point.X == 27)
            {
                timer2.Stop();
                timer1.Start();
                
            }
            if (label11Point.X == 599)
            {
                timer1.Stop();
                timer2.Start();
            }
        }
        Point label11Point = new Point(27, 32);
        private void timer1_Tick(object sender, EventArgs e)
        {

            while (label11Point.X <= 600)
            {
                label12.Text = label11Point.X.ToString();
                label11Point.X += 1;
                label11.Location = label11Point;
                break;
            }
                       
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            
            while (label11Point.X >= 27)
            {
                label12.Text = label11Point.X.ToString();
                label11Point.X -= 1;
                label11.Location = label11Point;
                break;
            }
            
        }
    }
}

标签被卡在表格的第600个像素处,不能移回。如何使它工作?

nkhmeac6

nkhmeac61#

我很惊讶你在timer tick处理程序中看到while循环导致的移动。如果你要这样做,为什么还要有一个timer呢?
在这个解决方案中,我有一个计时器,运动发生在计时器滴答声中。我还有三个可能的方向,右,左和停止(如果你想有一个开始/停止按钮)。
在Windows窗体设计器中,我在窗体上放置了一个标签和一个计时器,除了计时器的Interval属性(我将其设置为10(ms))外,其余属性都保持不变。
然后我添加了一个枚举和一个枚举示例作为Form类的字段:

public partial class Form1 : Form
{
    private enum Direction { MoveRight, MoveLeft, Stopped }
    Direction _direction;

    public Form1()
    {
        InitializeComponent();
    }
}

我在设计器中双击窗体的Caption区域创建了一个窗体Load处理程序,并添加了一个启动计时器的调用:

private void Form1_Load(object sender, EventArgs e)
{
    timer1.Start();
}

最后,我双击计时器以获得计时器Tick处理程序,并添加了一些代码:

private void timer1_Tick(object sender, EventArgs e)
{
    var curLocation = label1.Location;

    if (_direction == Direction.MoveRight && curLocation.X > 600)
    {
        _direction = Direction.MoveLeft;
    }
    else if (_direction == Direction.MoveLeft && curLocation.X < 27)
    {
        _direction = Direction.MoveRight;
    }
    int offset = _direction switch
    {
        Direction.MoveRight => 1,
        Direction.MoveLeft => -1,
        _ => 0,
    };

    curLocation.X += offset;
    label1.Location = curLocation;
}

_direction字段确定标签是向右还是向左移动。

没有计时器,您如何编写代码?"

您问 “没有计时器,您怎么写代码?" 我仍然对您的标签作为事件处理程序中的while循环的结果而移动感到惊讶-一定是我对Win32处理的旧理解发生了变化。
无论如何,我欺骗await调用Task.Delay而不是使用计时器。使用我现有的代码并执行以下操作:
1.在表单中加入两个按钮(一个标示为[开始](名为StartBtn),另一个标示为[停止](名为StopBtn))。
1.向类中添加另一个Direction类型的字段:Direction _previousDirection;
1.在Form1_Load处理程序中注解掉对timer1.Start();的调用
1.注解掉timer1_Tick方法中的所有代码(此时,如果需要,可以从窗体中删除计时器)
1.选择两个按钮(开始和停止)并按<Enter>。这将为两个按钮打开单击处理程序。
1.将StopBtn按钮的行程常式变更为如下所示:
新停止按钮代码:

private void StopBtn_Click(object sender, EventArgs e)
 {
     _previousDirection = _direction;
     _direction = Direction.Stopped;
 }

1.将StartBtn的处理程序更改为如下所示。请注意,while循环中的几乎所有内容(除了对Task.Delay的调用)都与前面的计时器tick处理程序代码相同。还请注意,我将处理程序设置为async void是为了允许await关键字发挥其作用。
启动按钮代码:

private async void StartBtn_Click(object sender, EventArgs e)
{
    _direction = _previousDirection;
     while (_direction != Direction.Stopped)
     {
        var curLocation = label1.Location;
         if (_direction == Direction.MoveRight && curLocation.X > 600)
        {
            _direction = Direction.MoveLeft;
        }
        else if (_direction == Direction.MoveLeft && curLocation.X < 27)
        {
            _direction = Direction.MoveRight;
        }
        int offset = _direction switch
        {
            Direction.MoveRight => 1,
            Direction.MoveLeft => -1,
            _ => 0,
        };

        curLocation.X += offset;
        label1.Location = curLocation;
        await Task.Delay(10);
    }
}
xsuvu9jc

xsuvu9jc2#

我解决了这个问题,我不知道为什么,但是在我的开篇文章中,Form1()函数只使一个if()条件起作用。然而,将if()语句放入计时器中解决了这个问题。现在,标题在指定的x轴间隔内来回移动。

namespace AlanCevreHesabiUygulamasi
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            timer1.Start();
        }
        Point label11Point = new Point(27, 32);
        private void timer1_Tick(object sender, EventArgs e)
        {

            while (label11Point.X >= 27)
            {
                label12.Text = label11Point.X.ToString();
                label11Point.X += 1;
                label11.Location = label11Point;
                break;
            }
            if (label11Point.X == 600)
            {
                timer2.Start();
                timer1.Stop();
            }

        }

        private void timer2_Tick(object sender, EventArgs e)
        {

            while (label11Point.X <= 600)
            {
                label12.Text = label11Point.X.ToString();
                label11Point.X -= 1;
                label11.Location = label11Point;
                break;
            }
            if (label11Point.X == 27)
            {
                timer1.Start();
                timer2.Stop();
            }
            
        }

相关问题