【问题标题】:How do I stop an animation with a timer if the animated object came to a specific location?如果动画对象到达特定位置,如何使用计时器停止动画?
【发布时间】:2019-05-11 14:51:13
【问题描述】:

我正在尝试在 C# Windows 窗体项目中使用面板和计时器制作一些动画。目前,有一个面板(在我的代码中称为“pnSideBlock”)位于窗口的左边缘。它旁边是一个按钮。

这个想法是,如果鼠标进入按钮,那么面板应该重新定位到窗口之外(在我的项目中,面板的宽度为 20px,因此我将其新位置设置为窗口外 20px)并将移动在计时器的帮助下再次进入它。一旦面板到达特定位置,在我的例子中是 0px,那么计时器应该停止并且面板应该停止移动。

但此刻,计时器一直在运行,这导致面板继续向右移动。

    private void btnMainMenu_MouseEnter(object sender, EventArgs e)
    {
        pnSideBlock.Left = -20;

        timerForAnim.Enabled = true;

        if(pnSideBlock.Left == 0)
        {
            timerForAnim.Enabled = false;
        }

    }

    private void btnMainMenu_MouseLeave(object sender, EventArgs e)
    {
        timerForAnim.Enabled = false;
    }

    private void timerForAnim_Tick(object sender, EventArgs e)
    {
        pnSideBlock.Left += 1;
    }

【问题讨论】:

    标签: c# windows winforms animation timer


    【解决方案1】:

    根据您的代码,您需要将其更改为:

    private void btnMainMenu_MouseEnter(object sender, EventArgs e)
        {
            pnSideBlock.Left = -20;
    
            timerForAnim.Enabled = true;
        }
    
        private void btnMainMenu_MouseLeave(object sender, EventArgs e)
        {
            timerForAnim.Enabled = false;
        }
    
        private void timerForAnim_Tick(object sender, EventArgs e)
        {
            pnSideBlock.Left += 1;
            if(pnSideBlock.Left == 0)
            {
                timerForAnim.Enabled = false;
            }
        }
    

    此更改是必需的,因为btnMainMenu_MouseEnter 仅在您使用鼠标输入按钮时发生一次。 并且您需要在每次移动后检查面板是否到位。

    【讨论】:

      【解决方案2】:

      类似的东西,使用异步方法。
      使您的 Button 的 MouseEnter 处理程序异步并调用 async Task SlidePanel() 方法,将控件的初始和最终位置指定为 slide 以及 动画 的速度(表示为毫秒)。

      当第一次进入 Control 时,它的 MouseEnter 处理程序是分离的(所以如果在动画播放时鼠标指针进入它就不会再次被提升)并在动画结束时再次连接。

      您可以像往常一样与按钮交互。
      即使按钮在单击时显示模式窗口(例如 MessageBox),动画也会执行到结束。

      视觉行为:

      private async Task SlidePanel(Control control, int start, int end, int speed)
      {
          while (start < end)
          {
              await Task.Delay(speed);
              start += 1;
              control?.BeginInvoke(new Action(() => control.Left += 1));
          }
      }
      
      private async void btnSlider_MouseEnter(object sender, EventArgs e)
      {
          btnMainMenu.MouseEnter -= btnMainMenu_MouseEnter;
          pnSideBlock.Left -= pnSideBlock.Width;
          await SlidePanel(pnSideBlock, pnSideBlock.Left, pnSideBlock.Width, 100);
          btnMainMenu.MouseEnter += btnMainMenu_MouseEnter;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 1970-01-01
        • 2014-03-31
        • 1970-01-01
        • 2023-03-25
        • 2020-02-26
        相关资源
        最近更新 更多