none
如何从后台线程启动并控制UI上的一个动画 RRS feed

  • 问题

  • 在UI主线程上生成这样一个动画(取自MSDN:http://msdn.microsoft.com/zh-cn/library/vstudio/ms590752.aspx),现在我希望从一个后台的线程中启动它(代码如下所示),怎么没有效果呢?

            private void btnBackInvoke_Click(object sender, RoutedEventArgs e)
            {
                backgroundWorker1.RunWorkerAsync();
            }

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                // Create a DoubleAnimation to animate the ScaleTransform.
                DoubleAnimation myAnimation = new DoubleAnimation
                    (
                        1, // "From" value
                        0.1, // "To" value
                        new Duration(TimeSpan.FromSeconds(1))
                    );

                // Create a clock the for the animation.
                myClock4Scale = myAnimation.CreateClock();

                // Associate the clock the ScaleX and
                // ScaleY properties of the button's
                // ScaleTransform.
                myButton.Dispatcher.BeginInvoke(new Action(() =>
                    myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleXProperty, myClock4Scale)), null);
                myButton.Dispatcher.BeginInvoke(new Action(() =>
                    myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleYProperty, myClock4Scale)), null);
            }


    2013年7月7日 11:46

答案

  • 通过点击按钮可以对一个动画启动、暂停、停止等,那就是说我们定义一个事件,在BackgroundWorker中触发这个事件,在这个事件处理函数(即代理指定的响应函数)中就可以控制动画了。通过编程试验,验证了这个方案可行。步骤如下所示:

    1.申明一个代理
      public delegate void FileOfferinBeginEventHandler(object sender, RoutedEventArgs e);

    2.在类中定义成员变量
      private BackgroundWorker bgwControlGinFile;
      private FileOfferinBeginEventHandler FileOfferinBegin;

    3.创建并运行后台线程
      // Start a thread to "offer" gop files from ingress to vpap
      bgwControlGinFile = new BackgroundWorker();
      bgwControlGinFile.DoWork += new DoWorkEventHandler(bgwControlGinFile_DoWork);
      bgwControlGinFile.RunWorkerAsync();

    4.创建事件响应函数
      private void AnimateGinfileBegin(object sender, RoutedEventArgs e)
      {
        clock4OfferInputX[i].Controller.Seek(TimeSpan.FromMilliseconds(0), TimeSeekOrigin.BeginTime);
      }

    5.在后台线程函数中创建事件代理的实例并触发事件
      void bgwControlGinFile_DoWork(object sender, DoWorkEventArgs e)
      {
        FileOfferinBegin += new FileOfferinBeginEventHandler(AnimateGinfileBegin);

        // Enter loop
        while (true)
        {
          this.Dispatcher.BeginInvoke(new Action(() => FileOfferinBegin(null, null)));
          Thread.Sleep(2200);
        }
      }

    • 已标记为答案 老笨猪 2013年7月11日 9:52
    2013年7月11日 9:52

全部回复

  • 重现了你所说的东西,但是怎么解决也是没有想法,求大神指导~

    2013年7月10日 11:02
  • 通过点击按钮可以对一个动画启动、暂停、停止等,那就是说我们定义一个事件,在BackgroundWorker中触发这个事件,在这个事件处理函数(即代理指定的响应函数)中就可以控制动画了。通过编程试验,验证了这个方案可行。步骤如下所示:

    1.申明一个代理
      public delegate void FileOfferinBeginEventHandler(object sender, RoutedEventArgs e);

    2.在类中定义成员变量
      private BackgroundWorker bgwControlGinFile;
      private FileOfferinBeginEventHandler FileOfferinBegin;

    3.创建并运行后台线程
      // Start a thread to "offer" gop files from ingress to vpap
      bgwControlGinFile = new BackgroundWorker();
      bgwControlGinFile.DoWork += new DoWorkEventHandler(bgwControlGinFile_DoWork);
      bgwControlGinFile.RunWorkerAsync();

    4.创建事件响应函数
      private void AnimateGinfileBegin(object sender, RoutedEventArgs e)
      {
        clock4OfferInputX[i].Controller.Seek(TimeSpan.FromMilliseconds(0), TimeSeekOrigin.BeginTime);
      }

    5.在后台线程函数中创建事件代理的实例并触发事件
      void bgwControlGinFile_DoWork(object sender, DoWorkEventArgs e)
      {
        FileOfferinBegin += new FileOfferinBeginEventHandler(AnimateGinfileBegin);

        // Enter loop
        while (true)
        {
          this.Dispatcher.BeginInvoke(new Action(() => FileOfferinBegin(null, null)));
          Thread.Sleep(2200);
        }
      }

    • 已标记为答案 老笨猪 2013年7月11日 9:52
    2013年7月11日 9:52